拡張返信
ちらつきは一切ありません。ctorのSetStyleがそれを処理します。「ちらつき」と表示されるのは、次の3つの要因によるアーティファクトの原因です。
- 更新レートはわずか10/秒です。それを20または30に増やしてみてください。
- 方向の値はコースです。時間/加速に基づく必要があります。それはあなたに残された運動です。
- 安っぽい「手」の画像には、硬いエイリアシングされたエッジがあります。更新の速度やアニメーションの速度に関係なく、ぎくしゃくしたように見えます。繰り返しになりますが、アンチエイリアス処理されたブレンドグラフィックス処理を行うことは演習として残されています。
コードをもっと注意深く見てください。これは「フォームにペイント」されたものではなく、カスタムコントロールです。からどのようにMetronomeControl
派生するかを参照してくださいControl
?MetronomeControlを追加してフォームを作成した方法をご覧ください。
画像ボックスは静止画像を表示するためのものであり、カスタムコントロール用ではありません。
更新する方法は、タイマーを作成することです。タイマーのTickイベントが発生すると、角度と方向が更新されます。より一般的には、コントロールの状態が更新されます。Invalidateを呼び出すと、オペレーティングシステムに、「ねえ、塗り直しが必要です。都合のよいときにWM_PAINTメッセージを送信してください」と通知されます。OnPaintオーバーライドは、コントロールの現在の状態をペイントするだけです。
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
class MetronomeControl : Control
{
private Bitmap hand;
private float angle = 0;
private float direction = 2;
private Timer timer = new Timer { Enabled = true, Interval = 30 };
public MetronomeControl()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.AllPaintingInWmPaint, true);
hand = CreateCrappyHandBitmap();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
if (angle < -45 || angle > 45)
direction = -direction;
angle += direction;
Invalidate();
}
private static Bitmap CreateCrappyHandBitmap()
{
Bitmap bitmap = new Bitmap(100, 300, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.Clear(Color.Transparent);
graphics.FillRectangle(Brushes.LightGray, 50 - 5, 0, 10, 300);
graphics.FillPolygon(Brushes.LightSlateGray, new Point[] { new Point(50 - 30, 40), new Point(50 + 30, 40), new Point(50 + 20, 80), new Point(50 - 20, 80) });
graphics.FillEllipse(Brushes.LightSlateGray, 0, 200, 100, 100);
}
return bitmap;
}
protected override void OnPaint(PaintEventArgs e)
{
// Erase background since we specified AllPaintingInWmPaint
e.Graphics.Clear(Color.AliceBlue);
e.Graphics.DrawString(Text, Font, Brushes.Black, new RectangleF(0, 0, ClientSize.Width, ClientSize.Height), new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
// Move the 0,0 point to the just below the bottom-center of our client area
e.Graphics.TranslateTransform(ClientSize.Width / 2, ClientSize.Height + 40);
// Rotate around this new 0,0
e.Graphics.RotateTransform(angle);
// Turn on AA to make it a bit less jagged looking
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// Draw the image so that the center of the ellipse is at 0,0
e.Graphics.DrawImage(hand, 0 - hand.Width / 2, 0 - hand.Height + 50);
// Reset the transform for other drawing
e.Graphics.ResetTransform();
base.OnPaint(e);
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form
{
Text = "Metronome Control Demo",
ClientSize = new Size(640, 480),
Controls =
{
new MetronomeControl
{
Location = new Point(10, 10),
Size = new Size (340, 300),
Font = new Font(FontFamily.GenericSansSerif, 24),
Text = "Metronome Control Demo",
}
}
});
}
}