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 以降のバージョンでは、この種類が含まれている、一般的なパッケージは、Windows オペレーティングシステムでのみサポートされています。 クロスプラットフォームアプリでこの型を使用すると、コンパイル時の警告と実行時例外が発生します。 詳細については、「system.string」を参照してください。 Windows でのみサポートされています。
注意
二重バッファリングを使用する最も簡単な方法は、メソッドを 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 クラスはスレッド セーフではありません。 別のスレッドからグラフィックス バッファーにアクセスする場合は、スレッド アクセス制御メカニズムを使用して競合を防ぐことが重要です。