- ベストアンサー
VB2005 PictureBox1に線を描きたい
VB2005 のPictureBox1に1秒毎に読込んできた値を折れ線グラフにして表示したいのですが、その方法を参考書を見ても良く分かりません。また、そのPictureBox1の上に別のフォームとかを表示すると、PictureBox1と重なった部分の表示が消えてしまいます。この2つを解決したいのですが。どなたか解決する方法を知っている方教えて頂きたいのですが。よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>例えば下記のように、Chart に描画処理を入れている場合、どうすればそこへ移行できるかを教えてほしいです。 Refreshメソッドを呼び出したときにPaintイベントが起動しますので(shimakichiさんが示したChartの処理が実行されます)、特別な処理を書く必要はありません。 描画処理を記述する位置はshimakichiさんが示した場所で問題ありません。
その他の回答 (4)
- HIROs-NET
- ベストアンサー率78% (15/19)
>PictureBox1に描画するのにPictureBox1プロパティのSize(700,250)ではなく、MaximumSize(27000,3800)のサイズで描画したいのですが、どうすれば良いのでしょうか?すみませんが教えて下さい。よろしくお願いします。 サイズがどうであろうと、描画するメソッド等にはなんら変わりはありません。 何をどう困っているのでしょうか? もう少し具体的に説明していただけますか?
お礼
HIROs-NET様 悩んでいろいろ試した結果できるようになりました。HIROs-NET様のおかげです。本当にありがとうございました。
補足
下記内容のコードを、Private Sub PictureBox1_Paint()に書いていますが、この処理を通った時は線を引いてくれるのですが、次にこの処理を通った場合、前回引いた線が消えてしまいます(今回この処理を通る場合、今回の線は引けます)。またY軸のスケールをMax(3800)で線を引きたいのにMax(250)になります。コードの書き方もおかしいところがあると思いますが、このコードを見て頂きアドバイスして頂きたいのですが。よろしくお願いします。 If ChartStartflg = True Then '描写スタート '縦軸等分線を引く i = Val(Chart_Y) For i = CInt(((250 - 0) / Val(Chart_Y))) To Int(250 / (Val(Chart_Y)) * (Val(Chart_Y) - 1)) Step Int(250 / Val(Chart_Y)) e.Graphics.DrawLine(Pens.Silver, 0, (PictureBox1.Size.Height - i), 700, (PictureBox1.Size.Height - i)) Next i '横軸等間隔線を引く For i = 1 To 9 e.Graphics.DrawLine(Pens.Silver, (i * 70), 0, (i * 70), 250) Next i If restartflg = False Then Dt1 = Val(Label_A.Text) If Dotcount = 0 Then Dt_old_A = Val(Label_A.Text) Else Dt_old_A = Val(Chart_Old_A) '前回の値 End If If MAXscal < Dt1 Then Ydot1 = 1 Ydot_old_A = (MAXscal - (Dt_old_A)) / Scaldot_Y Else If MINscal > Dt1 Then Ydot1 = 3792 Ydot_old_A = (MAXscal - (Dt_old_A)) / Scaldot_Y Else Ydot1 = (MAXscal - Dt1) * Scaldot_Y Ydot1 = MAXscal - Ydot1 If Ydot1 > 3799 Then Ydot1 = 247 '3792 End If Ydot_old_A = (MAXscal - Dt_old_A) * Scaldot_Y Ydot_old_A = MAXscal - Ydot_old_A If Ydot_old_A > 3799 Then Ydot_old_A = 247 '3792 End If End If End If Xcount_X = Xcount * Scaldot_X e.Graphics.FillRectangle(myBrush1, Xcount_X, Ydot1, 2, 2) Chart_Old_A = Val(Label_A.Text) e.Graphics.DrawLine(myPen1, Xcount_X, Ydot_old_A, Xcount_X, Ydot1) Else Chart_Old_A = Val(Label_A.Text) restartflg = False End If End if
- HIROs-NET
- ベストアンサー率78% (15/19)
Refreshメソッドは再描画したい場所で問題ないかと思います。 Do Loopを使用しているということなので、その中で行ってもかまいません。 指定した時間ごとに線を描画したいとのことですが、これは指定した時間ごとにPaintイベントが発生することからもわかるように、Paintイベント内ですべての描画を行うようにする必要があるかと思います。
補足
HIROs-NET様 指定した時間にペイントする処理に移行したい場合、どうすればそのペイント処理に移行できるのでしょうか?例えばコール文でその処理へ移行できるのでしょうか? 例えば下記のように、Chart に描画処理を入れている場合、どうすればそこへ移行できるかを教えてほしいです。 単に Call Chart としても引数が必要とでてしまいます。 また、下記コードの書き方でよろしいでしょうか? Sub Chart(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint ここに描写処理を入れる予定。 End sub よろしくお願いします。
- HIROs-NET
- ベストアンサー率78% (15/19)
私の環境では再現できませんでした。 描画処理が追いついていないということはありませんか? 試しに、5秒間隔とかにしてみてはどうでしょう? 再度申し上げますが PictureBox1.RefreshメソッドはTickイベント内に記述してください
補足
HIROs-NET様 私の質問の仕方(説明)が下手で申し訳ありません。 タイマーの件ですが、タイマーは使用していません。Do Loopの処理中に現在時間を読出し、その時間に何秒後に処理を行うという時間を足してその時間がくれば処理を行うようにしています。この為、Do Loopの中に入れて試してみようと思います。 下記は何らかのイベントが発生した時に行う処理というのはわかりました。(PictureBox1に線を描く場合、PictureBox1_Paintで描いておかないとPictureBox1.Refreshを行うと消えてしまうのですよね) Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint i = Val(Chart_Y) For i = Int(((250 - 0) / Val(Chart_Y))) To Int(250 / (Val(Chart_Y)) * (Val(Chart_Y) - 1)) Step Int(250 / Val(Chart_Y)) e.Graphics.DrawLine(Pens.Silver, 0, (PictureBox1.Size.Height - i), 700, (PictureBox1.Size.Height - i)) Next i For i = 1 To 9 e.Graphics.DrawLine(Pens.Silver, (i * 70), 0, (i * 70), 250) Next i End sub 下記のような時は、どうすれば良いでしょうか。 スタートボタンをクリックした時、指定した時間毎にPictureBox1に線を描写したい場合 もう少しでできそうなので、申し訳ありませんが教えて下さい。 よろしくお願いします。
- HIROs-NET
- ベストアンサー率78% (15/19)
PicutureBoxと重なった部分の表示が消えてしまうということですが、描画処理はどこに記述していますか? PictureBoxの場合はPaintイベント内で描画を行うのが一般的です。 Paintイベントの発生タイミングは、「再描画が必要なとき」となっているので、ほかのウィンドウに隠れて見えなくなっていたものが、再度トップウィンドウに表示される場合などにこのイベントが発生します。 よって線の描画はPaintイベント内で、Paintイベントの引数 e を使用します。 線を描画する場合は e.Graphics.DrawLine(Pens.Blue, 10, 10, 100, 100) などのようにします。 1秒ごとに処理を行うようにしているということなので、おそらくタイマーコントロールを使用しているかと思いますが、タイマーコントロールのTIckイベント内で PictureBox1.Refresh() のようにして、強制的に再描画させればこの問題は解決すると思われます。
補足
HIROs-NET様 早速の回答ありがとうございます。 Paintイベント内で描画しましたが、PictureBox1.Refreshとすると PictureBox1の画面が真っ白になったままとなります。これでは、1秒毎に描写している線も消えてしまうのではないでしょうか? (また、Paintイベント以外で描いた線は消えてしまいます) PictureBox1.Refreshの後に再度描画処理を入れないとだめなのでしょうか?申し訳ありませんが教えて下さい。
補足
HIROs-NET様 PictureBox1に描画するのにPictureBox1プロパティのSize(700,250)ではなく、MaximumSize(27000,3800)のサイズで描画したいのですが、どうすれば良いのでしょうか?すみませんが教えて下さい。よろしくお願いします。