ラベル ActiveControl の投稿を表示しています。 すべての投稿を表示
ラベル ActiveControl の投稿を表示しています。 すべての投稿を表示

2018年3月16日金曜日

MouseMoveイベントのON/OFF制御を実装しました

前回のエントリーで、CSVファイルからデータを取り込んでウインドウに描画する処理ができるようになりました。また、マウスイベントを使って、マウスカーソルの座標を取得し続けることも出来ています。

しかし、マウスカーソルの座標を取得し続ける必要があるのは、ある特定の条件の時だけ、今回のプログラムでは、輪切り画像を作るときだけです。それ以外の時には、イベントが発生しないでいてほしいのです。

ということで、色々調べ回って試行錯誤して、出来上がったのか下記リストです。前回のエントリーでやったことに対して、マウスカーソル座標の取得をcheckboxを使って有効にしたり無効にしたりできるようにしてあります。

checkBox1_CheckedChangedメソッドの中にその処理が書いてありますが、Delegateの登録と削除を普通にすればいいようです。感覚的には、一度登録しておいて、不要なときはマスク、ということにしたかったのですが、マスクする機能はどうやらないようで、マスクするためには、イベントハンドラーの中でマスク条件を吟味して不要なときは処理をしない、というコードを書かなければならず、無駄な処理になります。

例によって、Mainメソッドは省略です。
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualBasic.FileIO;

namespace CSVtoData2
{
    public partial class Form1 : Form
    {
        public static int mouse_x = 0, mouse_y = 0;

        public static ArrayList x_axis = new ArrayList();
        public static ArrayList y_axis = new ArrayList();
        public static ArrayList z_axis = new ArrayList();
        public static ArrayList dt = new ArrayList();

        public static bool button_on = false;

        public Form1()
        {
            InitializeComponent();
            Bitmap img = new Bitmap(Constants.size_pic_box_x, Constants.size_pic_box_y);

            Color col = new Color();

            try
            {
                using(TextFieldParser parser =
                    new TextFieldParser(Constants.FileName, 
                    System.Text.Encoding.GetEncoding("Shift_JIS")))
                {
                    parser.TextFieldType = FieldType.Delimited;
                    parser.SetDelimiters(","); // 区切り文字はコンマ
                    parser.CommentTokens = new string[1] { "#" };
                    int line = 0;

                    while (!parser.EndOfData)
                    {
                        string[] row = parser.ReadFields(); // 1行読んで、要素に分解、配列rowに格納

                        x_axis.Add(row[0]);  // ArrayListにX軸座標を追加
                        y_axis.Add(row[1]);  // ArrayListにY座標を追加
                        z_axis.Add(row[2]);  // ArrayListにZ座標を追加
                        dt.Add(row[3]);      // ArrayListにデータ本体を追加
                        ++line;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                Environment.Exit(0); // エラーが出たら強制終了
            }

            for( int i=0; i<x_axis.Count; ++i )
            {
                //
                // 実座標をウィンドウ座標に変換するためにオフセット加算
                //
                int x = (int)Convert.ToDouble(x_axis[i]) + Constants.offset_x;
                int y = -1 * ((int)Convert.ToDouble(y_axis[i])) + Constants.offset_y;
                int z = (int)Convert.ToDouble(z_axis[i]) + Constants.offset_z; 
                int d = (int)Convert.ToDouble(dt[i]);
          
                switch( d )
                {
                    case 0:
                        col = Color.Black;
                        break;
                    case 1:
                        col = Color.Blue;
                        break;
                    case 2:
                        col = Color.Red;
                        break;
                    case 3:
                        col = Color.Purple;
                        break;
                    case 4:
                        col = Color.Green;
                        break;
                    case 5:
                        col = Color.Yellow;
                        break;
                    case 6:
                        col = Color.Violet;
                        break;
                    case 7:
                        col = Color.White;
                        break;
                    default:
                        col = Color.Magenta;
                        break;
                }

                img.SetPixel(x, y, col);    
            }

            pictureBox1.Image = img;
            this.checkBox1.Focus();


        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            getMousePosition();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Environment.Exit((int)0);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)  //checkBox1イベント
        {
            if (checkBox1.Checked)
            {   //checkBox1がチェック状態であれば割り込みハンドラー登録
                this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
                checkBox1.Text = "push to event off";
                button_on = true;
            }
            else
            {   //checkBox1がチェックされていない状態であれば割り込みハンドラー登録削除
                this.pictureBox1.MouseMove -=  new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
                checkBox1.Text = "push to event on";
                button_on = false;
            }
        }

        /*
         * Form1が起動したときに、チェックボックスにフォーカスが当たるようにする
         */
        private void Form1_Load(object sender, EventArgs e)
        {
            this.ActiveControl = this.checkBox1;
        }

        private void getMousePosition()
        {
            if (checkBox1.Checked )
            {
                System.Drawing.Point cp = pictureBox1.PointToClient(Cursor.Position);

                mouse_x = cp.X - Constants.offset_x;
                mouse_y = -1 * cp.Y + Constants.offset_y;

                label1.Text = "x-size=" + pictureBox1.Size.Width;
                this.Text = "x=" + mouse_x + ":y=" + mouse_y + "(x=" + cp.X + ":y=" + cp.Y + ")";
            }
            else
            {
                mouse_x = mouse_y = (int)0xffff;
                label1.Text = "Not Focused";
                this.Text = "x=" + mouse_x + ":y=" + mouse_y;
            }

        }
    }
}
Formのデザインは上記のような感じで、Formの大きさ等は本質ではないので任意に。また、checkBoxは、プロパティの操作で外見をボタンのようにすることができるので、それを使ってボタンのような外見にしています(Appearanceプロパティです)。このフォームからできるVisual Studioの出力(Form1.Designer.cs)は、以下です。


namespace CSVtoData2
{
    partial class Form1
    {
        /// 
        /// 必要なデザイナー変数です。
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// 使用中のリソースをすべてクリーンアップします。
        /// 
        /// マネージ リソースを破棄する場合は true を指定し、その他の場合は false を指定します。
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows フォーム デザイナーで生成されたコード

        /// 
        /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディターで変更しないでください。
        /// 
        private void InitializeComponent()
        {
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.label1 = new System.Windows.Forms.Label();
            this.button2 = new System.Windows.Forms.Button();
            this.checkBox1 = new System.Windows.Forms.CheckBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // pictureBox1
            // 
            this.pictureBox1.BackColor = System.Drawing.SystemColors.Window;
            this.pictureBox1.Location = new System.Drawing.Point(38, 13);
            this.pictureBox1.Margin = new System.Windows.Forms.Padding(4);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(400, 400);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            //this.pictureBox1.MouseHover += new System.EventHandler(this.pictureBox1_MouseHover);
            //this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Font = new System.Drawing.Font("MS UI Gothic", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
            this.label1.Location = new System.Drawing.Point(197, 417);
            this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(55, 19);
            this.label1.TabIndex = 1;
            this.label1.Text = "label1";
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(38, 507);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(400, 28);
            this.button2.TabIndex = 3;
            this.button2.Text = "プログラム終了";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // checkBox1
            // 
            this.checkBox1.Appearance = System.Windows.Forms.Appearance.Button;
            this.checkBox1.AutoSize = true;
            this.checkBox1.Location = new System.Drawing.Point(38, 476);
            this.checkBox1.Name = "checkBox1";
            this.checkBox1.Size = new System.Drawing.Size(89, 25);
            this.checkBox1.TabIndex = 4;
            this.checkBox1.Text = "checkBox1";
            this.checkBox1.UseVisualStyleBackColor = true;
            this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(482, 547);
            this.Controls.Add(this.checkBox1);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.pictureBox1);
            this.Margin = new System.Windows.Forms.Padding(4);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.CheckBox checkBox1;
    }
}

動作させると下の動画のようになります。注目いただきたいのは、 小さな押しボタンの状態でウインドウ左上の数値の表示が動いたり止まったりすること。動いているときはMouseMoveイベントを受け付けているとき、止まっているときはMouseMoveイベントが受け付けられていないときです。
   
今回はこれで終わりにします。