[VC2010] LineArtを表示する方法

◆概要

この資料は、LineArtを表示する方法について記述しています。 Windows Xpに付属するスクリーンセーバー「ラインアート」のような線をフォームに表示します。この線を表示するにはDrawPolygonメソッドを使います。

◆前準備

  1. フォームにMenuStripを貼り付け、ファイルメニューを追加。その下にmenuFileStartとmenuFileCloseを追加します。
  2. フォームにツールボックスからPanelをドラッグして貼り付け、DockプロパティをFillにします。
  3. ◆サンプルコード

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Threading;// 追加
    
    namespace LineArtSample
    {
        public partial class Form1 : Form
        {
            // 変数
            private Graphics myGraphics;
            private threadClass ObjThread;
            private Thread thread;
    
            // コンストラクタ
            public Form1()
            {
                InitializeComponent();
                // フォームの整形
                this.Text = "LineArt";
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Width = 800;
                this.Height = 600;
                this.FormBorderStyle = FormBorderStyle.FixedSingle;
                // フォームの色
                this.BackColor = Color.Black;
                this.panel1.BackColor = Color.Black;
                
            }
            // ライン描画
            public void drawLine(Point[] sPoint, Point[] ePoint, Point[] gPoint, Point[] tPoint)
            {
                try
                {
                    Int32 index;
                    Pen blackPen = new Pen(Color.Black);
                    // 一番最後の線を消すためのポイント
                    Point[] ppb = new Point[4];
                    ppb[0] = new Point(sPoint[sPoint.Length - 1].X, sPoint[sPoint.Length - 1].Y);
                    ppb[1] = new Point(ePoint[ePoint.Length - 1].X, ePoint[ePoint.Length - 1].Y);
                    ppb[2] = new Point(gPoint[gPoint.Length - 1].X, gPoint[gPoint.Length - 1].Y);
                    ppb[3] = new Point(tPoint[tPoint.Length - 1].X, tPoint[tPoint.Length - 1].Y);
    
                    //  一番最後の線を消す
                    myGraphics.DrawPolygon(blackPen, ppb);
    
                    // 新しい線のポイント
                    Point[] pp = new Point[4];
                    pp[0] = new Point(sPoint[0].X, sPoint[0].Y);
                    pp[1] = new Point(ePoint[0].X, ePoint[0].Y);
                    pp[2] = new Point(gPoint[0].X, gPoint[0].Y);
                    pp[3] = new Point(tPoint[0].X, tPoint[0].Y);
                    
                    // ペンの色を赤にする
                    Pen newPen = new Pen(Color.Red);
                    
                    myGraphics.DrawPolygon(newPen, pp);
                    newPen.Dispose();
    
                    // データを移動
                    for (index = sPoint.Length - 1; index > 0; index--)
                    {
                        sPoint[index] = sPoint[index - 1];
                        ePoint[index] = ePoint[index - 1];
                        gPoint[index] = gPoint[index - 1];
                        tPoint[index] = tPoint[index - 1];
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            // デリゲートの宣言
            public delegate void deleDrawLine(Point[] sPoint, Point[] ePoint, Point[] gPoint, Point[] tPoint);
    
            #region Thread Class
            // スレッド・クラス
            public class threadClass
            {
                public Boolean bCpntinue;
                private int width;
                private int height;
                private deleDrawLine drawLine;
                Random rnd = new Random();
    
                // コンストラクタ
                public threadClass(int width, int height, deleDrawLine inDrawMethod)
                {
                    this.bCpntinue = false;     // スレッド制御
    
                    this.width = width;         // 各種初期化
                    this.height = height;
                    
                    drawLine = inDrawMethod;        // デリゲート
                }
    
                // スレッドメソッド
                public void wThread()
                {
                    int lines =7; // ラインの数を指定
                    
                    try
                    {
                        Point[] sPoint = new Point[lines];
                        Point[] ePoint = new Point[sPoint.Length];
                        Point[] gPoint = new Point[sPoint.Length];
                        Point[] tPoint = new Point[sPoint.Length];
    
                        // 移動量を指定する
                        Int32 index, dX = -2, dY = -2, dX2 = dX - 4, dY2 = dY - 4, 
                            dX3 = dX2 - 2, dY3 = dY2 - 2, dX4 = dX3 - 4, dY4 = dY3 - 2;
                        // スクリーンセーバーがスタートしたときの最初のPointを設定する
                        for (index = 0; index < sPoint.Length; index++)  // 配列初期化
                        {
                            sPoint[index].X = rnd.Next(0, width);
                            sPoint[index].Y = rnd.Next(0, height);
                            ePoint[index].X = rnd.Next(0, width);
                            ePoint[index].Y = rnd.Next(0, height);
                            gPoint[index].X = rnd.Next(0, width);
                            gPoint[index].Y = rnd.Next(0, height);
                            tPoint[index].X = rnd.Next(0, width);
                            tPoint[index].Y = rnd.Next(0, height);
                        }
                        while (bCpntinue)
                        {
                            // 境界のチェック
                            if (sPoint[0].X < 0 || sPoint[0].X >= this.width - 1)
                                dX = -dX;
                            if (sPoint[0].Y < 0 || sPoint[0].Y >= this.height - 1)
                                dY = -dY;
                            if (ePoint[0].X < 0 || ePoint[0].X >= this.width - 1)
                                dX2 = -dX2;
                            if (ePoint[0].Y < 0 || ePoint[0].Y >= this.height - 1)
                                dY2 = -dY2;
                            if (gPoint[0].X < 0 || gPoint[0].X >= this.width - 1)
                                dX3 = -dX3;
                            if (gPoint[0].Y < 0 || gPoint[0].Y >= this.height - 1)
                                dY3 = -dY3;
                            if (tPoint[0].X < 0 || tPoint[0].X >= this.width - 1)
                                dX4 = -dX4;
                            if (tPoint[0].Y < 0 || tPoint[0].Y >= this.height - 1)
                                dY4 = -dY4;
    
                            drawLine(sPoint, ePoint, gPoint, tPoint);
    
                            // 次の位置を計算
                            sPoint[0].X += dX;
                            sPoint[0].Y += dY;
                            ePoint[0].X += dX2;
                            ePoint[0].Y += dY2;
                            gPoint[0].X += dX3;
                            gPoint[0].Y += dY3;
                            tPoint[0].X += dX4;
                            tPoint[0].Y += dY4;
    
                            // 早すぎるのでウエイトを入れる
                            System.Threading.Thread.Sleep(10);
                        }
                    }
                    catch (System.Threading.ThreadAbortException)
                    {
                        MessageBox.Show("スレッドが停止した", "メッセージ");
                    }
                }
            }
            #endregion
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                try
                {
                    if (thread != null)       // スレッド動作中
                    {
                        if (thread.ThreadState != ThreadState.Running &&        // 実行中
                            thread.ThreadState != ThreadState.WaitSleepJoin)    // Sleep中
                        {
    			// スレッド・リスタート 
                            thread.Interrupt();  // .NET Framework2.0ではthread.Resume();                     
                        }
                        ObjThread.bCpntinue = false;        // スレッドに停止を通知
    
                        while (thread.IsAlive)       // スレッド停止を待つ
                            Thread.Sleep(10);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                
            }
    
            private void menuFileStart_Click(object sender, EventArgs e)
            {
                // スレッド・クラスのオブジェクトを作成
                ObjThread = new threadClass(panel1.Width, panel1.Height,
                    new deleDrawLine(drawLine));
    
                // グラフィックス・オブジェクトを作成
                myGraphics = Graphics.FromHwnd(panel1.Handle);
    
                // スレッド制御
                ObjThread.bCpntinue = true;
    
                // スレッドを作成
                thread = new Thread(new ThreadStart(ObjThread.wThread));
    
                // スレッドを開始する
                thread.Start();
            }
    
            private void menuFileClose_Click(object sender, EventArgs e)
            {
                this.Close();
            }
        }
    }
    
    ◆ダウンロード
    ダウンロードlineartsample.zip(50.1KB)

    動作確認:WindowsXp Professional、Windows Vista Ultimate 64ビット、Windows 7 Ultimate 64ビット
    必要なもの:.NET Framework 4.0


    ▼ページトップへ