Sdílet prostřednictvím


BufferedGraphics Třída

Definice

Poskytuje grafickou vyrovnávací paměť pro dvojité ukládání do vyrovnávací paměti.

public ref class BufferedGraphics sealed : IDisposable
public sealed class BufferedGraphics : IDisposable
type BufferedGraphics = class
    interface IDisposable
Public NotInheritable Class BufferedGraphics
Implements IDisposable
Dědičnost
BufferedGraphics
Implementuje

Příklady

Následující příklad kódu ukazuje použití objektu BufferedGraphics k vykreslení grafiky pomocí několika typů vyrovnávací paměti implementace. Kliknutím na formulář se střídavě spustí a zastaví časovač, který způsobuje aktualizace kreslení. Aktualizace kreslení umožňují pozorovat účinek dvojitého ukládání do vyrovnávací paměti. Kliknutí pravým tlačítkem myši na formulář prochází následující režimy výkresu:

V každém režimu je vykreslen text, který identifikuje aktuální režim a popisuje chování, ke kterému dochází při stisknutí každého tlačítka myši.

#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
#using <System.dll>

using namespace System;
using namespace System::ComponentModel;
using namespace System::Drawing;
using namespace System::Windows::Forms;

namespace BufferingExample
{
   public ref class BufferingExample: public Form
   {
   private:
      BufferedGraphicsContext^ context;
      BufferedGraphics^ grafx;
      Byte bufferingMode;
      array<String^>^bufferingModeStrings;
      System::Windows::Forms::Timer^ timer1;
      Byte count;

   public:
      BufferingExample()
         : Form()
      {
         array<String^>^tempStrings = {"Draw to Form without OptimizedDoubleBufferring control style","Draw to Form using OptimizedDoubleBuffering control style","Draw to HDC for form"};
         bufferingModeStrings = tempStrings;

         // Configure the Form for this example.
         this->Text = "User double buffering";
         this->MouseDown += gcnew MouseEventHandler( this, &BufferingExample::MouseDownHandler );
         this->Resize += gcnew EventHandler( this, &BufferingExample::OnResize );
         this->SetStyle( static_cast<ControlStyles>(ControlStyles::AllPaintingInWmPaint | ControlStyles::UserPaint), true );

         // Configure a timer to draw graphics updates.
         timer1 = gcnew System::Windows::Forms::Timer;
         timer1->Interval = 200;
         timer1->Tick += gcnew EventHandler( this, &BufferingExample::OnTimer );
         bufferingMode = 2;
         count = 0;

         // Retrieves the BufferedGraphicsContext for the 
         // current application domain.
         context = BufferedGraphicsManager::Current;

         // Sets the maximum size for the primary graphics buffer
         // of the buffered graphics context for the application
         // domain.  Any allocation requests for a buffer larger 
         // than this will create a temporary buffered graphics 
         // context to host the graphics buffer.
         context->MaximumBuffer = System::Drawing::Size( this->Width + 1, this->Height + 1 );

         // Allocates a graphics buffer the size of this form
         // using the pixel format of the Graphics created by 
         // the Form.CreateGraphics() method, which returns a 
         // Graphics object that matches the pixel format of the form.
         grafx = context->Allocate( this->CreateGraphics(), Rectangle(0,0,this->Width,this->Height) );

         // Draw the first frame to the buffer.
         DrawToBuffer( grafx->Graphics );
      }

   private:
      void MouseDownHandler( Object^ /*sender*/, MouseEventArgs^ e )
      {
         if ( e->Button == ::MouseButtons::Right )
         {
            // Cycle the buffering mode.
            if ( ++bufferingMode > 2 )
                        bufferingMode = 0;

            // If the previous buffering mode used 
            // the OptimizedDoubleBuffering ControlStyle,
            // disable the control style.
            if ( bufferingMode == 1 )
                        this->SetStyle( ControlStyles::OptimizedDoubleBuffer, true );

            // If the current buffering mode uses
            // the OptimizedDoubleBuffering ControlStyle,
            // enabke the control style.
            if ( bufferingMode == 2 )
                        this->SetStyle( ControlStyles::OptimizedDoubleBuffer, false );

            // Cause the background to be cleared and redraw.
            count = 6;
            DrawToBuffer( grafx->Graphics );
            this->Refresh();
         }
         else
         {
            
            // Toggle whether the redraw timer is active.
            if ( timer1->Enabled )
                        timer1->Stop();
            else
                        timer1->Start();
         }
      }

   private:
      void OnTimer( Object^ /*sender*/, EventArgs^ /*e*/ )
      {
         // Draw randomly positioned ellipses to the buffer.
         DrawToBuffer( grafx->Graphics );

         // If in bufferingMode 2, draw to the form's HDC.
         if ( bufferingMode == 2 )

         // Render the graphics buffer to the form's HDC.
         grafx->Render( Graphics::FromHwnd( this->Handle ) );
         // If in bufferingMode 0 or 1, draw in the paint method.
         else

         // If in bufferingMode 0 or 1, draw in the paint method.
         this->Refresh();
      }

      void OnResize( Object^ /*sender*/, EventArgs^ /*e*/ )
      {
         // Re-create the graphics buffer for a new window size.
         context->MaximumBuffer = System::Drawing::Size( this->Width + 1, this->Height + 1 );
         if ( grafx != nullptr )
         {
            delete grafx;
            grafx = nullptr;
         }

         grafx = context->Allocate( this->CreateGraphics(), Rectangle(0,0,this->Width,this->Height) );

         // Cause the background to be cleared and redraw.
         count = 6;
         DrawToBuffer( grafx->Graphics );
         this->Refresh();
      }

      void DrawToBuffer( Graphics^ g )
      {
         // Clear the graphics buffer every five updates.
         if ( ++count > 5 )
         {
            count = 0;
            grafx->Graphics->FillRectangle( Brushes::Black, 0, 0, this->Width, this->Height );
         }

         // Draw randomly positioned and colored ellipses.
         Random^ rnd = gcnew Random;
         for ( int i = 0; i < 20; i++ )
         {
            int px = rnd->Next( 20, this->Width - 40 );
            int py = rnd->Next( 20, this->Height - 40 );
            g->DrawEllipse( gcnew Pen( Color::FromArgb( rnd->Next( 0, 255 ), rnd->Next( 0, 255 ), rnd->Next( 0, 255 ) ), 1.0f ), px, py, px + rnd->Next( 0, this->Width - px - 20 ), py + rnd->Next( 0, this->Height - py - 20 ) );
         }

         // Draw information strings.
         g->DrawString( String::Format( "Buffering Mode: {0}", bufferingModeStrings[ bufferingMode ] ), gcnew System::Drawing::Font( "Arial",8 ), Brushes::White, 10, 10 );
         g->DrawString( "Right-click to cycle buffering mode", gcnew System::Drawing::Font( "Arial",8 ), Brushes::White, 10, 22 );
         g->DrawString( "Left-click to toggle timed display refresh", gcnew System::Drawing::Font( "Arial",8 ), Brushes::White, 10, 34 );
      }

   protected:
      virtual void OnPaint( PaintEventArgs^ e ) override
      {
         grafx->Render( e->Graphics );
      }
   };
}

[STAThread]
int main()
{
   Application::Run( gcnew BufferingExample::BufferingExample );
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace BufferingExample
{
    public class BufferingExample : Form
    {
        private BufferedGraphicsContext context;
        private BufferedGraphics grafx;

    private byte bufferingMode;
    private string[] bufferingModeStrings =
        { "Draw to Form without OptimizedDoubleBufferring control style",
          "Draw to Form using OptimizedDoubleBuffering control style",
          "Draw to HDC for form" };

    private System.Windows.Forms.Timer timer1;
    private byte count;

        public BufferingExample() : base()
        {
            // Configure the Form for this example.
            this.Text = "User double buffering";
            this.MouseDown += new MouseEventHandler(this.MouseDownHandler);
            this.Resize += new EventHandler(this.OnResize);
            this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true );

            // Configure a timer to draw graphics updates.
        timer1 = new System.Windows.Forms.Timer();
        timer1.Interval = 200;
        timer1.Tick += new EventHandler(this.OnTimer);

        bufferingMode = 2;
        count = 0;

            // Retrieves the BufferedGraphicsContext for the
            // current application domain.
            context = BufferedGraphicsManager.Current;

            // Sets the maximum size for the primary graphics buffer
            // of the buffered graphics context for the application
            // domain.  Any allocation requests for a buffer larger
            // than this will create a temporary buffered graphics
            // context to host the graphics buffer.
            context.MaximumBuffer = new Size(this.Width+1, this.Height+1);

            // Allocates a graphics buffer the size of this form
            // using the pixel format of the Graphics created by
            // the Form.CreateGraphics() method, which returns a
            // Graphics object that matches the pixel format of the form.
            grafx = context.Allocate(this.CreateGraphics(),
                 new Rectangle( 0, 0, this.Width, this.Height ));

        // Draw the first frame to the buffer.
        DrawToBuffer(grafx.Graphics);
        }

    private void MouseDownHandler(object sender, MouseEventArgs e)
        {
        if( e.Button == MouseButtons.Right )
        {
                 // Cycle the buffering mode.
             if( ++bufferingMode > 2 )
                     bufferingMode = 0;

                 // If the previous buffering mode used
                 // the OptimizedDoubleBuffering ControlStyle,
                 // disable the control style.
                 if( bufferingMode == 1 )
                     this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );

                 // If the current buffering mode uses
                 // the OptimizedDoubleBuffering ControlStyle,
                 // enabke the control style.
                 if( bufferingMode == 2 )
                     this.SetStyle( ControlStyles.OptimizedDoubleBuffer, false );

                 // Cause the background to be cleared and redraw.
                 count = 6;
                 DrawToBuffer(grafx.Graphics);
         this.Refresh();
        }
        else
        {
                // Toggle whether the redraw timer is active.
        if( timer1.Enabled )
            timer1.Stop();
        else
            timer1.Start();
        }
        }

    private void OnTimer(object sender, EventArgs e)
    {
            // Draw randomly positioned ellipses to the buffer.
        DrawToBuffer(grafx.Graphics);

            // If in bufferingMode 2, draw to the form's HDC.
        if( bufferingMode == 2 )
                    // Render the graphics buffer to the form's HDC.
            grafx.Render(Graphics.FromHwnd(this.Handle));
            // If in bufferingMode 0 or 1, draw in the paint method.
        else
            this.Refresh();
    }

        private void OnResize(object sender, EventArgs e)
        {
           // Re-create the graphics buffer for a new window size.
           context.MaximumBuffer = new Size(this.Width+1, this.Height+1);
           if( grafx != null )
           {
           grafx.Dispose();
               grafx = null;
           }
           grafx = context.Allocate(this.CreateGraphics(),
               new Rectangle( 0, 0, this.Width, this.Height ));

           // Cause the background to be cleared and redraw.
           count = 6;
           DrawToBuffer(grafx.Graphics);
       this.Refresh();
        }	

    private void DrawToBuffer(Graphics g)
    {
            // Clear the graphics buffer every five updates.
        if( ++count > 5 )
            {
                count = 0;
                grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height);
            }

            // Draw randomly positioned and colored ellipses.
        Random rnd = new Random();
        for( int i=0; i<20; i++ )
        {
        int px = rnd.Next(20,this.Width-40);
        int py = rnd.Next(20,this.Height-40);
        g.DrawEllipse(new Pen(Color.FromArgb(rnd.Next(0, 255), rnd.Next(0,255), rnd.Next(0,255)), 1),
            px, py, px+rnd.Next(0, this.Width-px-20), py+rnd.Next(0, this.Height-py-20)); 	    			
        }

            // Draw information strings.
        g.DrawString("Buffering Mode: "+bufferingModeStrings[bufferingMode], new Font("Arial", 8), Brushes.White, 10, 10);
            g.DrawString("Right-click to cycle buffering mode", new Font("Arial", 8), Brushes.White, 10, 22);
            g.DrawString("Left-click to toggle timed display refresh", new Font("Arial", 8), Brushes.White, 10, 34);
    }

    protected override void OnPaint(PaintEventArgs e)
        {
        grafx.Render(e.Graphics);
    }

        [STAThread]
        public static void Main(string[] args)
        {
        Application.Run(new BufferingExample());
        }
    }
}
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms

Public Class BufferingExample
    Inherits Form
    Private context As BufferedGraphicsContext
    Private grafx As BufferedGraphics
    
    Private bufferingMode As Byte
    Private bufferingModeStrings As String() = _
        {"Draw to Form without OptimizedDoubleBufferring control style", _
         "Draw to Form using OptimizedDoubleBuffering control style", _
         "Draw to HDC for form"}
    
    Private timer1 As System.Windows.Forms.Timer
    Private count As Byte    
    
    Public Sub New()
        ' Configure the Form for this example.
        Me.Text = "User double buffering"
        AddHandler Me.MouseDown, AddressOf Me.MouseDownHandler
        AddHandler Me.Resize, AddressOf Me.ResizeHandler
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint, True)
        
        ' Configure a timer to draw graphics updates.
        timer1 = New System.Windows.Forms.Timer()
        timer1.Interval = 200
        AddHandler timer1.Tick, AddressOf Me.OnTimer
        
        bufferingMode = 2
        count = 0
        
        ' Retrieves the BufferedGraphicsContext for the 
        ' current application domain.
        context = BufferedGraphicsManager.Current
        
        ' Sets the maximum size for the primary graphics buffer
        ' of the buffered graphics context for the application
        ' domain.  Any allocation requests for a buffer larger 
        ' than this will create a temporary buffered graphics 
        ' context to host the graphics buffer.
        context.MaximumBuffer = New Size(Me.Width + 1, Me.Height + 1)
        
        ' Allocates a graphics buffer the size of this form
        ' using the pixel format of the Graphics created by 
        ' the Form.CreateGraphics() method, which returns a 
        ' Graphics object that matches the pixel format of the form.
        grafx = context.Allocate(Me.CreateGraphics(), _
            New Rectangle(0, 0, Me.Width, Me.Height))
        
        ' Draw the first frame to the buffer.
        DrawToBuffer(grafx.Graphics)
    End Sub    
    
    Private Sub MouseDownHandler(sender As Object, e As MouseEventArgs)
        If e.Button = MouseButtons.Right Then
            ' Cycle the buffering mode.
            bufferingMode = bufferingMode+1
            If bufferingMode > 2 Then
                bufferingMode = 0
            End If 
            ' If the previous buffering mode used 
            ' the OptimizedDoubleBuffering ControlStyle,
            ' disable the control style.
            If bufferingMode = 1 Then
                Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
            End If 
            ' If the current buffering mode uses
            ' the OptimizedDoubleBuffering ControlStyle,
            ' enabke the control style.
            If bufferingMode = 2 Then
                Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
            End If 
            ' Cause the background to be cleared and redraw.
            count = 6
            DrawToBuffer(grafx.Graphics)
            Me.Refresh()
        Else
            ' Toggle whether the redraw timer is active.
            If timer1.Enabled Then
                timer1.Stop()
            Else
                timer1.Start()
            End If
        End If
    End Sub
     
    Private Sub OnTimer(sender As Object, e As EventArgs)
        ' Draw randomly positioned ellipses to the buffer.
        DrawToBuffer(grafx.Graphics)
        
        ' If in bufferingMode 2, draw to the form's HDC.
        If bufferingMode = 2 Then
            ' Render the graphics buffer to the form's HDC.
            grafx.Render(Graphics.FromHwnd(Me.Handle))
        ' If in bufferingMode 0 or 1, draw in the paint method.
        Else
            Me.Refresh()
        End If
    End Sub
     
    Private Sub ResizeHandler(sender As Object, e As EventArgs)
        ' Re-create the graphics buffer for a new window size.
        context.MaximumBuffer = New Size(Me.Width + 1, Me.Height + 1)
        If (grafx IsNot Nothing) Then
            grafx.Dispose()
            grafx = Nothing
        End If
        grafx = context.Allocate(Me.CreateGraphics(), New Rectangle(0, 0, Me.Width, Me.Height))
        
        ' Cause the background to be cleared and redraw.
        count = 6
        DrawToBuffer(grafx.Graphics)
        Me.Refresh()
    End Sub    
    
    Private Sub DrawToBuffer(g As Graphics)
        ' Clear the graphics buffer every five updates.
        count = count+1
        If count > 5 Then
            count = 0
            grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, Me.Width, Me.Height)
        End If
        
        ' Draw randomly positioned and colored ellipses.
        Dim rnd As New Random()
        Dim i As Integer
        For i = 0 To 21
            Dim px As Integer = rnd.Next(20, Me.Width - 40)
            Dim py As Integer = rnd.Next(20, Me.Height - 40)
            g.DrawEllipse(New Pen(Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), _
                rnd.Next(0, 255)), 1), px, py, px + rnd.Next(0, Me.Width - px - 20), _
                py + rnd.Next(0, Me.Height - py - 20))
        Next i
        
        ' Draw information strings.
        g.DrawString("Buffering Mode: " + bufferingModeStrings(bufferingMode), _
            New Font("Arial", 8), Brushes.White, 10, 10)
        g.DrawString("Right-click to cycle buffering mode", New Font("Arial", 8), _
            Brushes.White, 10, 22)
        g.DrawString("Left-click to toggle timed display refresh", _
            New Font("Arial", 8), Brushes.White, 10, 34)
    End Sub    
    
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        grafx.Render(e.Graphics)
    End Sub   
    
    <STAThread()>  _
    Public Shared Sub Main(args() As String)
        Application.Run(New BufferingExample())
    End Sub

End Class

Poznámky

Třída BufferedGraphics umožňuje implementovat vlastní dvojité ukládání do vyrovnávací paměti pro grafiku. Poskytuje obálku grafické vyrovnávací paměti spolu s metodami, které můžete použít k zápisu do vyrovnávací paměti a vykreslení jejího obsahu do výstupního zařízení.

Grafika, která používá dvojité ukládání do vyrovnávací paměti, může snížit nebo eliminovat blikání způsobené překreslením plochy zobrazení. Při použití dvojité vyrovnávací paměti se aktualizovaná grafika nejprve nakreslí do vyrovnávací paměti a obsah této vyrovnávací paměti se pak rychle zapíše na některé nebo všechny zobrazené plochy. Toto poměrně krátké přepsání zobrazené grafiky obvykle snižuje nebo eliminuje blikání, ke kterému někdy dochází při aktualizaci grafiky.

Poznámka

V rozhraní .NET 6 a novějších verzích je balíček System.Drawing.Common, který obsahuje tento typ, podporován pouze v operačních systémech Windows. Použití tohoto typu v multiplatformních aplikacích způsobuje upozornění na kompilaci a výjimky za běhu. Další informace najdete v tématu System.Drawing.Common podporované pouze ve Windows.

Poznámka

Nejjednodušší způsob, jak použít dvojité ukládání do vyrovnávací paměti, je nastavit OptimizedDoubleBuffer příznak stylu ovládacího prvku pomocí SetStyle metody . Nastavení příznaku OptimizedDoubleBuffer ovládacího prvku přesměruje veškeré malování ovládacího prvku prostřednictvím výchozí grafické vyrovnávací paměti, aniž by bylo nutné provést další kód. Tento příznak je ve výchozím nastavení nastavený na true hodnotu .

Třída BufferedGraphics nemá žádný veřejný konstruktor a musí být vytvořena pomocí BufferedGraphicsContext metody pro doménu Allocate aplikace. Z statické BufferedGraphicsManager.Current vlastnosti můžete načíst BufferedGraphicsContext pro aktuální doménu aplikace.

Vlastnost Graphics lze použít pro kreslení do grafické vyrovnávací paměti. Tato vlastnost poskytuje přístup k objektu Graphics , který nakreslí do grafické vyrovnávací paměti přidělené pro tento BufferedGraphics objekt.

Metoda Render bez argumentů vykreslí obsah grafické vyrovnávací paměti na plochu zadanou při přidělení vyrovnávací paměti. Další přetížení metody umožňují určit Graphics objekt nebo IntPtr objekt, který odkazuje na kontext zařízení, do kterého chcete nakreslit Render obsah grafické vyrovnávací paměti.

Další informace o kreslení grafiky s dvojitou vyrovnávací pamětí naleznete v tématu Double Buffered Graphics.

Vlastnosti

Graphics

Graphics Získá objekt, který výstup do grafické vyrovnávací paměti.

Metody

Dispose()

Uvolní všechny prostředky používané objektem BufferedGraphics .

Equals(Object)

Určí, zda se zadaný objekt rovná aktuálnímu objektu.

(Zděděno od Object)
Finalize()

Umožňuje objektu pokusit se uvolnit prostředky a provést další operace čištění předtím, než je uvolněna uvolňováním paměti.

GetHashCode()

Slouží jako výchozí hashovací funkce.

(Zděděno od Object)
GetType()

Type Získá z aktuální instance.

(Zděděno od Object)
MemberwiseClone()

Vytvoří mělkou kopii aktuálního Objectsouboru .

(Zděděno od Object)
Render()

Zapíše obsah grafické vyrovnávací paměti do výchozího zařízení.

Render(Graphics)

Zapíše obsah grafické vyrovnávací paměti do zadaného Graphics objektu.

Render(IntPtr)

Zapíše obsah grafické vyrovnávací paměti do kontextu zařízení přidruženého k zadanému IntPtr úchytu.

ToString()

Vrátí řetězec, který představuje aktuální objekt.

(Zděděno od Object)

Platí pro

Bezpečný přístup z více vláken

Třída BufferedGraphics není bezpečná pro přístup z více vláken. Při přístupu k grafické vyrovnávací paměti ze samostatných vláken je důležité použít mechanismus řízení přístupu vlákna, aby se zabránilo konfliktům.

Viz také