C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: ピクチャボックス上で動くマウスの軌跡を描くプログラム


(過去ログ 116 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■68578 / inTopicNo.1)  ピクチャボックス上で動くマウスの軌跡を描くプログラム
  
□投稿者/ yoto (1回)-(2013/10/29(Tue) 19:26:51)

分類:[C#] 

VC#2010を使い始めたばかりの初心者である私は、ボタンを押すとピクチャボックス上で動くマウスの座標に●を描き、軌跡を描きたいと考えています。エラーは吐かれず、コンパイルはうまくいっているのですが、なぜかマウスを動かしても一つも●がピクチャボックス上がひとつも表示されませんでした。いくつかのサイトを回ってもなかなか解決できずに行き詰ってしまったので投稿させていただきました。
間違っている個所のご指摘やプログラムの添削を行っていただけると幸いです。以下に自分が作製したプログラムを記載します。

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 WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        int index = 0;
        int Max = 0;
        int a = 0;
        int[] x = new int[100];
        int[] y = new int[100];

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //フォーム上の座標 (10, 20) にマウスポインタを移動する
            //クライアント座標を画面座標に変換する
            System.Drawing.Point mp = pictureBox1.PointToScreen( new System.Drawing.Point(300, 200));
            //マウスポインタの位置を設定する
            System.Windows.Forms.Cursor.Position = mp;

            while (a == 0)
            {
                Mousechase();
                Drawpoint();
                //一秒間(1000ミリ秒)停止する
                System.Threading.Thread.Sleep(1000);
            }

        }

        private void Mousechase()//マウスの位置を格納する
        {
            
            //ピクチャボックス上の座標でマウスポインタの位置を取得する
            //画面座標でマウスポインタの位置を取得する
            System.Drawing.Point sp = System.Windows.Forms.Cursor.Position;
            //画面座標をクライアント座標に変換する
            System.Drawing.Point cp = pictureBox1.PointToClient(sp);
            //X座標を取得する
            x[index]= cp.X;
            //Y座標を取得する
            y[index] = cp.Y;

            index++;
            Max = index;

        }

        private void Drawpoint()
        {
            for (int b = 0; b <=Max ; b++)
            {
                //描画先とするImageオブジェクトを作成する
                Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
                //ImageオブジェクトのGraphicsオブジェクトを作成する
                Graphics u = Graphics.FromImage(canvas);
                //フォントオブジェクトの作成
                Font fnt1 = new Font("MS UI Gothic", 5);
                //●を、青色で表示
                u.DrawString("●", fnt1, Brushes.Blue, y[index] - 2, x[index]- 2);
                //PictureBox1に表示する
                pictureBox1.Image = canvas;
            }
        }


        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

 初めての投稿なので見にくい部分が多く申し訳ないのですが、よろしくお願い致します。

引用返信 編集キー/
■68579 / inTopicNo.2)  Re[1]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ しま (35回)-(2013/10/29(Tue) 21:24:21)
No68578 (yoto さん) に返信
> VC#2010を使い始めたばかりの初心者である私は、ボタンを押すとピクチャボックス上で動くマウスの座標に●を描き、軌跡を描きたいと考えています。エラーは吐かれず、コンパイルはうまくいっているのですが、なぜかマウスを動かしても一つも●がピクチャボックス上がひとつも表示されませんでした。いくつかのサイトを回ってもなかなか解決できずに行き詰ってしまったので投稿させていただきました。
> 間違っている個所のご指摘やプログラムの添削を行っていただけると幸いです。以下に自分が作製したプログラムを記載します。

おそらく、思っている動きが実現できないからここに投稿したと思いますが、あなたのプログラムを
読み手に実行して(思い通りにならない)原因を調べた上で、教えて欲しいということですか?
そうでないなら、提示したコードで何が問題なのか示して下さい。

又、フォーム上の座標(10,20)が System.Drawing.Point(300, 200) でいい訳を教えてください

ボタンのクリックイベントから戻るためには a != 0 となる必要があると思いますがいつどこで変数 a の値が変わるのでしょうか?
ボタンのクリックイベント中に DrawString で描画しても、再描画する度に消えてしまうので良い考えとは言えないでしょう。
 ボタンのクリックイベント中に描画していますが画面には反映できないようなコードになっていませんか?
文字は単純な画像(線や点)ではないので数ドットしか離れていない場合、既に描画した文字に or では描画しません
(背景色の部分は背景色で塗潰す)ので、丸の外の部分が背景色で欠けてしまうことがあります。
Mousechase() の index++; では何故配列の上限の検査をしなくていいのでしょうか?
他にもありますが、まずまともに動きそうなコードにすることが先ではないかと考えます。

MouseDown で座標を拾うのを開始して、 MouseUp で座標を拾うのを止めるようにするのがいいでしょう。
移動先の座標を拾うのは MouseMove で行いましょう。
そうすれば、 sleep(1000) なんてことはしなくて済むでしょう。
引用返信 編集キー/
■68580 / inTopicNo.3)  Re[2]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ しま (36回)-(2013/10/29(Tue) 21:31:16)
No68579 (しま さん) に返信
> ■No68578 (yoto さん) に返信
>>VC#2010を使い始めたばかりの初心者である私は、ボタンを押すとピクチャボックス上で動くマウスの座標に●を描き、軌跡を描きたいと考えています。エラーは吐かれず、コンパイルはうまくいっているのですが、なぜかマウスを動かしても一つも●がピクチャボックス上がひとつも表示されませんでした。いくつかのサイトを回ってもなかなか解決できずに行き詰ってしまったので投稿させていただきました。
>>間違っている個所のご指摘やプログラムの添削を行っていただけると幸いです。以下に自分が作製したプログラムを記載します。
>
> おそらく、思っている動きが実現できないからここに投稿したと思いますが、あなたのプログラムを
> 読み手に実行して(思い通りにならない)原因を調べた上で、教えて欲しいということですか?
> そうでないなら、提示したコードで何が問題なのか示して下さい。

送信後に、どう動いているか書かれていることに気付きました。
上の文章は読み飛ばしてください。申し訳ありません。
引用返信 編集キー/
■68581 / inTopicNo.4)  Re[1]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ Azulean (228回)-(2013/10/29(Tue) 22:57:11)
No68578 (yoto さん) に返信
図表モードを使われる際は、適当に改行を入れてください。
そうしないと非常に横長になって読みづらくなります。

> なぜかマウスを動かしても一つも●がピクチャボックス上がひとつも表示されませんでした。

それはあなたが while ループの中で無限ループさせているからです。
Windows はメッセージループという考え方があり、画面に絵を描く、ユーザーからのマウスやキーボードの操作を受け取るためにはメッセージを受け取る必要があります。
しかし、あなたは無限ループを書いたことで、メッセージループに戻らず、Image プロパティに代入しようとその更新がずっと先延ばしになっています。

基本的に無限にループさせるコードは書かないことを志してください。

今回の場合、ボタンのクリックイベントで入力を受け付けるようにフィールド変数を設定して、MouseMove イベントで座標の記憶と描画の更新、何らかのボタンを押したイベントなどでフィールド変数の設定の解除と最後の座標の記憶・画像の更新を作り込むとよいでしょう。
引用返信 編集キー/
■68582 / inTopicNo.5)  Re[2]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ yoto (2回)-(2013/10/30(Wed) 11:13:49)
No68581 (Azulean さん) に返信
> ■No68578 (yoto さん) に返信
 ご返信とご指摘ありがとうございます。
 早速、そのようにプログラムを書いてみてみました
 軌跡は描けるようになったのですが、どうもピクチャボックスとフォームの領域近くでしか軌跡を描画できませんでした。
 (ピクチャボックスの中心にマウスを動かしても、軌跡を描くことができません)

 再度、修正したプログラムを記述しますのでよろしくお願い致します

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;
using System.Diagnostics;

namespace WindowsFormsApplication1
{

    public partial class Form1 : Form
    {
        int draw_flag = 0;
        Stopwatch sw;
        const int intervalTime = 100; // msなので0.1秒間隔でマウス座標を取得
        const int maxpoint = 100; // 最大100個の座標これ以上は先頭から削除
        List<Point> drawPoints; // 座標を格納するList
        public Form1()
        {
            InitializeComponent();
            drawPoints = new List<Point>();
            sw = new Stopwatch();
            sw.Start();
            this.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            // drawフラグた立っていれば
            if (draw_flag == 1)
            {
                // インターバルタイム以上経過していれば
                if (sw.ElapsedMilliseconds >= intervalTime)
                {
                    // マウス座標を格納する最大数以上なら先頭の座標をリストから削除
                    if (drawPoints.Count >= maxpoint)
                    {
                        drawPoints.RemoveAt(0);
                    }
                    // マウス座標を格納
                    drawPoints.Add(new Point(e.X, e.Y));
                    // ストップウォッチリセット・スタート
                    sw.Reset();
                    sw.Start();
                    // 描画
                    DrawPoints();
                }
            }
        }

        void DrawPoints()
        {
            Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            Graphics u = Graphics.FromImage(canvas);
            Font fnt1 = new Font("MS UI Gothic", 5);
            foreach (Point p in drawPoints)
            {
                u.DrawString("●", fnt1, Brushes.Blue, p);
            }
            pictureBox1.Image = canvas;
            u.Dispose();
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            draw_flag ^= 1;

            if (draw_flag == 0)
            {
                Text = "描画しない";

            }
            else if (draw_flag == 1)
            {
                Text = "描画する";
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}


引用返信 編集キー/
■68583 / inTopicNo.6)  Re[3]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ しま (37回)-(2013/10/30(Wed) 12:16:24)
No68582 (yoto さん) に返信
>  再度、修正したプログラムを記述しますのでよろしくお願い致します

マウス移動のイベントで渡ってくるマウス座標の値を見てみましょう
マウス移動のイベントで得られるマウス座標とピクチャーボックス内のマウス座標と
に違いがあることに気付くことと思います
ピクチャーボックス内に描画したいのだからピクチャーボックスの座標に合わせればいいと思いますよ

ピクチャーボックスに表示するビットマップを予め用意しておいて、そこに新たに得た座標に対して
描画すれば、座標の取得と、描画とが分離できるので、(Invalidate() や Refresh() や Update() などで)
再描画させるだけで常に最新の状態が表示できるでしょう
>
>
> void DrawPoints()
> {
> Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
> Graphics u = Graphics.FromImage(canvas);
> Font fnt1 = new Font("MS UI Gothic", 5);
> foreach (Point p in drawPoints)
> {
> u.DrawString("●", fnt1, Brushes.Blue, p);
> }
> pictureBox1.Image = canvas;
> u.Dispose();
> }
>
>
引用返信 編集キー/
■68584 / inTopicNo.7)  Re[3]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ shu (409回)-(2013/10/30(Wed) 12:54:40)
No68582 (yoto さん) に返信

> this.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);
pictureBox1.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);

でないと駄目です。
引用返信 編集キー/
■68585 / inTopicNo.8)  Re[4]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ yoto (4回)-(2013/10/30(Wed) 13:40:14)
No68583 (しま さん) に返信

 ありがとうございます。
 自分なりに調べてみて格納するマウス座標をピクチャボックスを基準とした座標に変換するプログラムを追加してみました。
 あと、ご指摘された通りにあらかじめ画像を用意しピクチャボックスに表示するようにもしてみました。

 ですが、軌跡が表示される範囲がピクチャボックスとフォームの領域付近という問題が解決できませんでした。
  なにぶん、質問者の私がC#初心者なものでしまさんの思っている通りのプログラムを書くことができなかったかもしれません。

 お手数をおかけして申し訳ございませんが、再度添削をお願いできませんでしょうか?

 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;
using System.Diagnostics;

namespace WindowsFormsApplication1
{

    public partial class Form1 : Form
    {
        int draw_flag = 0;
        Stopwatch sw;
        const int intervalTime = 100; // msなので0.1秒間隔でマウス座標を取得
        const int maxpoint = 100; // 最大100個の座標これ以上は先頭から削除
        List<Point> drawPoints; // 座標を格納するList

        (修正部分☆)Bitmap bmp = (Bitmap)System.Drawing.Image.FromFile(@"C:\\Users\\yoto\\Desktop\\実験画像フォルダ\\WhiteBack.png"); 
        
        public Form1()
        {
            InitializeComponent();
            drawPoints = new List<Point>();
            sw = new Stopwatch();
            sw.Start();
            this.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            // drawフラグた立っていれば
            if (draw_flag == 1)
            {
                // インターバルタイム以上経過していれば
                if (sw.ElapsedMilliseconds >= intervalTime)
                {
                    // マウス座標を格納する最大数以上なら先頭の座標をリストから削除
                    if (drawPoints.Count >= maxpoint)
                    {
                        drawPoints.RemoveAt(0);
                    }

      (修正部分☆)/*画像座標でのマウスポインタの位置を取得する
                    System.Drawing.Point sp = System.Windows.Forms.Cursor.Position;
                    //画面座標をクライアント座標(ピクチャボックス座標)に変換する
                    System.Drawing.Point cp = pictureBox1.PointToClient(sp);
                    drawPoints.Add(new Point(cp.X, cp.Y));*/
                   
           // ストップウォッチリセット・スタート
                    sw.Reset();
                    sw.Start();
                    // 描画
                    DrawPoints();
                }
            }
        }

        void DrawPoints()
        {
            Graphics u = Graphics.FromImage(bmp);
            Font fnt1 = new Font("MS UI Gothic", 5);
            foreach (Point p in drawPoints)
            {
                u.DrawString("●", fnt1, Brushes.Blue, p);
            }
            pictureBox1.Image = bmp;
            u.Dispose();
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            draw_flag ^= 1;

            if (draw_flag == 0)
            {
                Text = "描画しない";

            }
            else if (draw_flag == 1)
            {
                Text = "描画する";
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}

引用返信 編集キー/
■68586 / inTopicNo.9)  Re[4]: ピクチャボックス上で動くマウスの軌跡を描くプログラム
□投稿者/ yoto (5回)-(2013/10/30(Wed) 13:47:03)
No68584 (shu さん) に返信
> ■No68582 (yoto さん) に返信
>
>>this.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);
> pictureBox1.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);
>
> でないと駄目です。

SHUさん本当にありがとうございます。
ご指摘の通りに修正しましたら、問題を解決することができました!

しまさん、Azuleanさんも何度もプログラムの添削に付き合っていただきありがとうございます!!

コメントだけで感謝の気持ちを伝えるしかなく誠に申し訳ないのですが、本当にありがとうございました。
また、同じように質問を投稿すると思うのでその時はよろしくお願いたします。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -