Partager via


BufferedGraphics Classe

Définition

Fournit une mémoire tampon de graphiques pour la double mise en mémoire tampon.

public ref class BufferedGraphics sealed : IDisposable
public sealed class BufferedGraphics : IDisposable
type BufferedGraphics = class
    interface IDisposable
Public NotInheritable Class BufferedGraphics
Implements IDisposable
Héritage
BufferedGraphics
Implémente

Exemples

L’exemple de code suivant illustre l’utilisation d’un BufferedGraphics objet pour dessiner des graphiques à l’aide de plusieurs types d’implémentations de mise en mémoire tampon. Le fait de cliquer sur le formulaire démarre et arrête un minuteur qui provoque des mises à jour de dessin. Les mises à jour de dessin vous permettent d’observer l’effet d’une double mise en mémoire tampon. Cliquez avec le bouton droit sur le formulaire pour parcourir les modes de dessin suivants :

Dans chaque mode, du texte est dessiné qui identifie le mode actuel et décrit le comportement qui se produit lorsque chaque bouton de la souris est appuyé.

#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

Remarques

La BufferedGraphics classe vous permet d’implémenter une double mise en mémoire tampon personnalisée pour vos graphiques. Il fournit un wrapper pour une mémoire tampon graphique, ainsi que des méthodes que vous pouvez utiliser pour écrire dans la mémoire tampon et afficher son contenu sur un périphérique de sortie.

Les graphiques qui utilisent une double mise en mémoire tampon peuvent réduire ou éliminer le scintillement provoqué par le redessinage d’une surface d’affichage. Lorsque vous utilisez une double mise en mémoire tampon, les graphiques mis à jour sont d’abord dessinés dans une mémoire tampon, et le contenu de cette mémoire tampon est ensuite rapidement écrit dans tout ou partie de la surface affichée. Ce remplacement relativement bref des graphiques affichés réduit ou élimine généralement le scintillement qui se produit parfois lorsque les graphiques sont mis à jour.

Notes

Dans .NET 6 et versions ultérieures, le package System.Drawing.Common, qui inclut ce type, est pris en charge uniquement sur les systèmes d’exploitation Windows. L’utilisation de ce type dans les applications multiplateformes provoque des avertissements au moment de la compilation et des exceptions d’exécution. Pour plus d’informations, consultez System.Drawing.Common uniquement pris en charge sur Windows.

Notes

La façon la plus simple d’utiliser la double mise en mémoire tampon consiste à définir l’indicateur de OptimizedDoubleBuffer style de contrôle sur un contrôle à l’aide de la SetStyle méthode . La définition de l’indicateur OptimizedDoubleBuffer d’un contrôle redirige toute la peinture du contrôle via une mémoire tampon graphique par défaut, sans nécessiter de code supplémentaire. Cet indicateur est défini true sur par défaut.

La BufferedGraphics classe n’a pas de constructeur public et doit être créée par pour un domaine d’application à l’aide BufferedGraphicsContext de sa Allocate méthode . Vous pouvez récupérer pour BufferedGraphicsContext le domaine d’application actuel à partir de la propriété statique BufferedGraphicsManager.Current .

La Graphics propriété peut être utilisée pour dessiner dans la mémoire tampon graphique. Cette propriété permet d’accéder à l’objet Graphics qui dessine dans la mémoire tampon graphique allouée pour cet BufferedGraphics objet.

La Render méthode sans argument dessine le contenu de la mémoire tampon graphique sur la surface spécifiée lors de l’allocation de la mémoire tampon. D’autres surcharges de la Render méthode vous permettent de spécifier un Graphics objet ou un IntPtr objet qui pointe vers un contexte d’appareil vers lequel dessiner le contenu de la mémoire tampon graphique.

Pour plus d’informations sur le dessin de graphiques à double mise en mémoire tampon, consultez Graphiques en mémoire tampon double.

Propriétés

Graphics

Obtient un objet Graphics qui est dirigé vers la mémoire tampon de graphiques.

Méthodes

Dispose()

Libère toutes les ressources utilisées par l'objet BufferedGraphics.

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.

(Hérité de Object)
Finalize()

Autorise un objet à tenter de libérer des ressources et à exécuter d'autres opérations de nettoyage avant qu'il ne soit récupéré par une opération garbage collection.

GetHashCode()

Fait office de fonction de hachage par défaut.

(Hérité de Object)
GetType()

Obtient le Type de l'instance actuelle.

(Hérité de Object)
MemberwiseClone()

Crée une copie superficielle du Object actuel.

(Hérité de Object)
Render()

Écrit le contenu de la mémoire tampon de graphiques dans l'appareil par défaut.

Render(Graphics)

Écrit le contenu de la mémoire tampon de graphiques dans l'objet Graphics spécifié.

Render(IntPtr)

Écrit le contenu de la mémoire tampon de graphiques dans le contexte de périphérique associé au handle IntPtr spécifié.

ToString()

Retourne une chaîne qui représente l'objet actuel.

(Hérité de Object)

S’applique à

Cohérence de thread

La classe BufferedGraphics n'est pas thread-safe. Lors de l’accès à une mémoire tampon graphique à partir de threads distincts, il est important d’utiliser un mécanisme de contrôle d’accès aux threads pour éviter les conflits.

Voir aussi