*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

<C#>
「マウスのホイール操作で、キャラクター画像を回転させる画像処理を、マルチスレッドで行なう。<時間差改善版>」のコード No.8


*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

.






元のページ


元ページ「<C# > マウスのホイール操作で、キャラクター画像を回転させる画像処理を、マルチスレッドで行なう。<時間差改善版>」
http://note.chiebukuro.yahoo.co.jp/detail/n166043

 

記述量上限の制限で、ページを分けて記述しています。






本ページの前のページ


「マウスのホイール操作で、キャラクター画像を回転させる画像処理を、マルチスレッドで行なう。<時間差改善版>」のコード No.7
http://note.chiebukuro.yahoo.co.jp/detail/n171222

 

記述量上限の制限で、ページを分けて記述しています。







はじめに


元ページの「<C#> マウスのホイール操作で、キャラクター画像を回転させる画像処理を、マルチスレッドで行なう。<時間差改善版>」におけるコードをここに記述します。








Formクラスのコード



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


// マウスのホイール操作で、キャラクター画像を回転
// させる画像処理を、マルチスレッドで行なう。
namespace RotateThreadSimple2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


            // スレッドからテキストボックスをアクセスすることを指定
            Control.CheckForIllegalCrossThreadCalls = false;
        }

 

        //============
        // メンバー変数


        // 要求電文処理受付クラス
        private GraphicsAcceptanceThread GraphicsAcceptanceObj;

 


        // 回転関係の属性値
        public double RotateAngle;  // 回転角度(マウスホイールの回転で増減させる量)
        public double Rotate_Step;   // ホイールのスクロールイベント発生時の回転角度(ホイール量)増分

 


        // 画像指定
        private Image CharacterImg;

        private void Form1_Load(object sender, EventArgs e)
        {

            // 画像指定
            CharacterImg = new Bitmap("C:キャラクター.bmp"); // キャラクター画像


            // 要求電文処理受付クラスオブジェクトを生成
            GraphicsAcceptanceObj = new GraphicsAcceptanceThread();


            // 画像処理完了時イベントプロシージャとするメソッドの登録
            GraphicsAcceptanceObj.MoveImageEvent += new GraphicsAcceptanceThread.MoveImageDelegate(Arithmetic1_FinishArithmetic);


            // ログ関連情報伝達時のイベントプロシージャとするメソッドの登録
            GraphicsAcceptanceObj.LogMessageEvent += new GraphicsAcceptanceThread.LogMessageMethodDelegate(Arithmetic1_LogMessage);

 


            // マウスホイールの動作時に起動するイベントプロシージャを登録
            this.pictureBox1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseWheel);


            // コントロールの初期化
            button1.Text = "受付開始";
            button2.Text = "受付終了";
            button3.Text = "一時中断";
            button4.Text = "再開始";
            label1.Text = "開始時は、「受付開始」ボタンをクリックして下さい。";


            // ボタンの有効/無効の設定
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;

 

            // 回転角度(マウスホイールの回転で増減させる量)
            RotateAngle = 0.0;


            // ホイールのスクロールイベント発生時の回転角度(ホイール量)増分
            Rotate_Step = 0.1;


            // ピクチャボックスを選択します。
            //  --- <注意> ピクチャボックスが選択されている状態でないと、マウスホイール
            //             のイベントの活用が不可能になります。
            pictureBox1.Select();

        }

 

        //============
        // フォームクローズ時イベント
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

            // フォームを非表示にする。
            //  --- この後のアプリケーションソフトの終了処理(すなわち、本フ
            //      ォームの終了処理)では、少し時間がかかります。よって、ユ
            //      ーザーは、終了操作(「閉じる」ボタンのクリック)を既に行
            //      なっているのに、本フォームがなかなか閉じないことになりま
            //      す(終了処理に、時間がかかるので)。そして、そのようにフ
            //      ォームが閉じないと、ユーザーは、誤動作をしたのかと勘違い
            //      をしてしまいます。よって、そのような誤解を招かないように、
            //      本フォームを非表示にしてから、終了関係の処理を行なうこと
            //      にします。
            this.Visible = false;


            // 要求電文処理受付クラスオブジェクトのリソース解放
            // (受け付け用スレッドの終了などを行なう)
            GraphicsAcceptanceObj.Dispose();


            // 短時間だけ待機
            //  --- スレッドがメソッドを呼び出したタイミングでアプリケーショ
            //      ンソフトを終了すると、そのメソッドが処理し切れないで実行
            //      時エラーになることがあります。すなわち、もう既に、該当メ
            //      ソッドの処理を実行し始めているのに、そのメソッドがアクセ
            //      スするコントロール等が破棄されている場合は、実行時エラー
            //      になります(なお、ここで言っているメソッドとは、イベント
            //      プロシージャ等のプログラミング上定義したメソッドだけでは
            //      なく、WindowsAPI等のシステム側が内部的に呼び出している機
            //      能も含みます)。よって、上方の Dispose()メソッドでスレッ
            //      ドの終了をして、その後、下方の処理で短時間だけ待機します。
            //      そうすれば、既に実行を始めてしまったメソッドが終了してか
            //      ら、その後にアプリケーションソフトの終了処理(コントロー
            //      ル等の破棄)が行なわれます。その結果、前述の実行時エラー
            //      は発生しません。
            System.Threading.Thread.Sleep(7000);    // 短時間だけ待機

 

        }

 

        //============
        // スレッド開始用ボタン
        private void button1_Click(object sender, EventArgs e)
        {
            GraphicsAcceptanceObj.AcceptanceStart();


            // ピクチャボックスを選択します。
            //  --- <注意> ピクチャボックスが選択されている状態でないと、マウスホイール
            //             のイベントの活用が不可能になります。
            pictureBox1.Select();


            // ボタンの有効/無効の設定
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = false;

        }


        //============
        // スレッド終了用ボタン
        private void button2_Click(object sender, EventArgs e)
        {
            GraphicsAcceptanceObj.AcceptanceEnd();

 

            // ピクチャボックスを選択します。
            //  --- <注意> ピクチャボックスが選択されている状態でないと、マウスホイール
            //             のイベントの活用が不可能になります。
            pictureBox1.Select();


            // ボタンの有効/無効の設定
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;

        }


        //============
        // スレッド一時中断用ボタン
        private void button3_Click(object sender, EventArgs e)
        {
            GraphicsAcceptanceObj.AcceptanceSuspend();


            // ピクチャボックスを選択します。
            //  --- <注意> ピクチャボックスが選択されている状態でないと、マウスホイール
            //             のイベントの活用が不可能になります。
            pictureBox1.Select();


            // ボタンの有効/無効の設定
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = false;
            button4.Enabled = true;

        }


        //============
        // スレッド再開始用ボタン
        private void button4_Click(object sender, EventArgs e)
        {
            GraphicsAcceptanceObj.AcceptanceRestart();


            // ピクチャボックスを選択します。
            //  --- <注意> ピクチャボックスが選択されている状態でないと、マウスホイール
            //             のイベントの活用が不可能になります。
            pictureBox1.Select();


            // ボタンの有効/無効の設定
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = false;

        }

 

        // ==============
        // マウスホイール動作時起動のイベントプロシージャ
        private void pictureBox1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
        {


            // スクロール結果取得
            GetResultWhichScrolled(
                e,  // スクロール時イベントプロシージャの第2引数
                ref RotateAngle, // 増減量
                //Zoom_Max,       // 増減量の最大値上限
                //Zoom_Min,       // 増減量の最小値下限
                Rotate_Step);     // ホイール量増分


            // 要求電文の生成
            RequiredCall Required_Call = new RequiredCall();


            // 要求電文のパラメーターを設定
            Required_Call.ImageData = CharacterImg;
            Required_Call.PositionX = e.X;
            Required_Call.PositionY = e.Y;
            Required_Call.BackgroundColor = Brushes.White;
            Required_Call.BackgroundWidth = pictureBox1.ClientSize.Width;
            Required_Call.BackgroundHeight = pictureBox1.ClientSize.Height;
            Required_Call.RotateAngle = (float)RotateAngle;


            // 画像処理機能の非同期呼び出し用メソッドを実行して、スレッドを開始。
            //  --- なお、処理結果は、イベントと言う形で返却されます。
            GraphicsAcceptanceObj.InvokeRequest(Required_Call);

        }

 

        //============
        // 画像処理終了時に起動するイベントプロシージャ
        public void Arithmetic1_FinishArithmetic(object sender, RequiredCall Required_Call, System.Drawing.Image ans)
        {

            // ピクチャボックスに処理結果の画像を設定。
            pictureBox1.Image = ans;

        }


        //============
        // ログメッセージ発生時のイベントプロシージャ
        public void Arithmetic1_LogMessage(object sender, string Log_Message)
        {

            // 結果表示
            label1.Text = Log_Message;

        }

 

        // ==============
        // スクロール結果取得メソッド
        // マウスホイールをスクロールした結果を取得する。
        // 第1引数: スクロール時に起動するイベントプロシージャの第
        //           2引数を、本メソッドの本引数に入力指定
        // 第2引数: マウスホイールの回転で増減させる量
        // 第3引数: 量の最大値上限
        // 第4引数: 量の最小値下限
        // 第5引数: ホイールのスクロールイベント発生時のホイール量増分
        public void GetResultWhichScrolled(
            System.Windows.Forms.MouseEventArgs e,
            ref double Wheel_Value,
            //double Max_Value,
            //double Min_Value,
            double Wheel_Step)
        {

            // e.Deltaで、マウス ホイールの回転回数を表す符合付きの数値を取得。
            // それをWheelValueに増加
            if (e.Delta >= 0)
            {
                Wheel_Value += Wheel_Step;
            }
            else
            {
                Wheel_Value -= Wheel_Step;
            }


            double TwoPI = 2.0 * Math.PI;

            // 角度の値が大きく成り過ぎた場合の処理
            if (Wheel_Value >= TwoPI)
            {
                Wheel_Value = Wheel_Value - TwoPI;
            }
            // 角度が負で、その絶対値が大きく成り過ぎた場合の処理
            else if (Wheel_Value <= -1.0 * TwoPI)
            {
                Wheel_Value = Wheel_Value + TwoPI;
            }
            else
            {
                // 未処理
            }

        }

 

    }
}




さいごに


本ページの内容説明については、元ページを参照して下さい。