BufferedGraphics クラス
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
ダブル バッファリングのためのグラフィックス バッファーを提供します。
public ref class BufferedGraphics sealed : IDisposable
public sealed class BufferedGraphics : IDisposable
type BufferedGraphics = class
interface IDisposable
Public NotInheritable Class BufferedGraphics
Implements IDisposable
- 継承
-
BufferedGraphics
- 実装
例
次のコード例では、 オブジェクトを BufferedGraphics 使用して、いくつかの種類のバッファリング実装を使用してグラフィックスを描画する方法を示します。 フォームを交互にクリックすると、描画の更新が発生するタイマーが開始および停止します。 描画の更新により、ダブル バッファリングの効果を確認できます。 フォームを右クリックすると、次の描画モードが切り抜けられます。
コントロール スタイルを使用して OptimizedDoubleBuffer メソッドをOnPaintオーバーライドして描画します。
コントロール スタイルを OnPaint 使用 OptimizedDoubleBuffer せずにフォーム メソッドのメソッドをオーバーライドして描画します。
各モードでは、現在のモードを識別し、各マウス ボタンが押されたときに発生する動作を記述するテキストが描画されます。
#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
注釈
BufferedGraphicsクラスを使用すると、グラフィックスのカスタム ダブル バッファリングを実装できます。 グラフィックス バッファーのラッパーと、バッファーに書き込み、その内容を出力デバイスにレンダリングするために使用できるメソッドが提供されます。
二重バッファリングを使用するグラフィックスは、表示サーフェスの再描画によって引き起こされるちらつきを減らすか、または排除できます。 ダブル バッファリングを使用すると、更新されたグラフィックスが最初にメモリ内のバッファーに描画され、このバッファーの内容が表示されるサーフェスの一部またはすべてにすばやく書き込まれます。 通常、表示されるグラフィックスを比較的簡単に上書きすると、グラフィックスの更新時に発生するちらつきが軽減または排除されます。
注意
.NET 6 以降のバージョンでは、この種類を含む System.Drawing.Common パッケージは Windows オペレーティング システムでのみサポートされています。 クロスプラットフォーム アプリでこの型を使用すると、コンパイル時の警告と実行時の例外が発生します。 詳細については、「 Windows でのみサポートされる System.Drawing.Common」を参照してください。
注意
二重バッファリングを使用する最も簡単な方法は、 メソッドを OptimizedDoubleBuffer 使用してコントロールにコントロール スタイル フラグを SetStyle 設定することです。 コントロールのフラグを OptimizedDoubleBuffer 設定すると、追加のコードを必要とせずに、既定のグラフィックス バッファーを介してコントロールのすべての描画がリダイレクトされます。 このフラグは既定で に true
設定されています。
クラスにはBufferedGraphicsパブリック コンストラクターがなく、そのAllocateメソッドを使用してアプリケーション ドメインの によってBufferedGraphicsContext作成される必要があります。 現在のアプリケーション ドメインの を BufferedGraphicsContext 静的 BufferedGraphicsManager.Current プロパティから取得できます。
プロパティは Graphics 、グラフィックス バッファーへの描画に使用できます。 このプロパティは、このBufferedGraphicsオブジェクトにGraphics割り当てられたグラフィックス バッファーに描画する オブジェクトへのアクセスを提供します。
引数を指定しない メソッドは Render 、バッファーが割り当てられたときに指定されたサーフェスにグラフィックス バッファーの内容を描画します。 メソッドの他のオーバーロードを使用すると、グラフィックス バッファーのRender内容を描画するデバイス コンテキストを指すオブジェクトまたはIntPtrオブジェクトを指定Graphicsできます。
ダブル バッファーグラフィックスの描画の詳細については、「 ダブル バッファーグラフィックス」を参照してください。
プロパティ
Graphics |
グラフィックス バッファーに出力する Graphics オブジェクトを取得します。 |
メソッド
Dispose() |
この BufferedGraphics オブジェクトによって使用されているすべてのリソースを解放します。 |
Equals(Object) |
指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。 (継承元 Object) |
Finalize() |
オブジェクトが、ガベージ コレクションによって収集される前に、リソースの解放とその他のクリーンアップ操作の実行を試みることができるようにします。 |
GetHashCode() |
既定のハッシュ関数として機能します。 (継承元 Object) |
GetType() |
現在のインスタンスの Type を取得します。 (継承元 Object) |
MemberwiseClone() |
現在の Object の簡易コピーを作成します。 (継承元 Object) |
Render() |
グラフィックス バッファーの内容を既定のデバイスに書き込みます。 |
Render(Graphics) |
グラフィックス バッファーの内容を指定された Graphics オブジェクトに書き込みます。 |
Render(IntPtr) |
グラフィックス バッファーの内容を、指定した IntPtr ハンドルに関連付けられているデバイス コンテキストに書き込みます。 |
ToString() |
現在のオブジェクトを表す文字列を返します。 (継承元 Object) |
適用対象
スレッド セーフ
BufferedGraphics クラスはスレッド セーフではありません。 別のスレッドからグラフィックス バッファーにアクセスする場合は、スレッド アクセス制御メカニズムを使用して競合を防ぐことが重要です。
こちらもご覧ください
.NET