none
描画した画面に別のWIN画面が上に重なった後外れると重なり部分の描画画面が消えてしまいます。 RRS feed

  • 質問

  • VB2005でフォ-ム上にグラフを描かせています。描画した画面の上に別のWIN画面が一度重なって外れると せっかく描画した画面の
    重なった部分が消されて白くなってしまいます。これを避ける方法を探していますが まだ判りません。フォームのプロパティーの設定とか
    さわってみましたが見つかりませんでした。以前使っていたVB6では こんな不具合は出なかったのに・・・・
    よろしく お願いします。
    2010年1月11日 2:52

回答

すべての返信

  • どうやってグラフを描画しているのでしょうか?

    Windows アプリケーションは基本的に、重なった部分についてもう一度描き直す、再描画という処理が必要になっています。
    VB6 の頃はプロパティの設定によっては勝手に実行されたかもしれませんが、.NET 世代の VB2005 では基本的に自身でそのコードを書かないといけません。

    下記のページにあるように、Paint イベントで描画するようにするか、一度、Bitmap に描きこんでしまって、それを Image プロパティに設定するかなどの対応を取る必要があります。
    http://dobon.net/vb/dotnet/graphics/pictureboximageanddrawimage.html
    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年1月11日 3:35
    モデレータ
  • Azulean様

    早速回答をいただき ありがとうございます。
    再描画の処理を行う必要がある事は 判りました。現在 Dim g as graphics と定義してg.DrawLine / g.FillRectangle で
    描画しています。ご案内頂いたURLを参考にしてBitmapに一度描きこんでPaintイベントで再描画したら うまく描画はできました。
    しかしBitmapに描きこむタイミング=”他の画面が重なった時” をイベントの中から探していますが見つけられずにいます。
    windows対応の基本常識レベルの質問で申し訳ありませんがヒントだけでも よろしくお願いします。
    2010年1月12日 0:35
  • 外池と申します。

    2段階のステップがあることはご理解されてますよね? Bitmapにグラフを描くステップと、そのBitmapをFormに描くステップと。

    A)あるBitmapが既に用意されているとして、ユーザーはアプリケーション自身の「窓」も、他のアプリケーションの「窓」も、チャカチャカ勝手に動かしますから、「窓」が後ろに隠れたり前に現れたり、画面の縁に隠れたりまた現れたり、その都度再描画が必要になります。これは、PaintイベントでOSから通知が来ますので、その都度BitmapをFormに描けば良いわけです。

    B)それに先立つBitmapに肝心のグラフを描くのは、uri_uriさんのお考え次第で、どのタイミングでも良いのですが・・・。普通は、ユーザーがボタンを押したりしたときに、データを整理してグラフに描く動作をする、という感じではないでしょうか。

    で・・・、何が見つからないのか・・・、と推察するに、A)のPaintイベントと、B)のBitmapに描くところが分離しちゃっていて、プログラムの実行として繋がらないということでしょうか?

    だとすれば、2つ解決方法があります。私としては前者がお奨めです。

    ひとつは、アプリからOSに再描画を促す方法があります。FormのInvalidateメソッドです。そうすると、OSはA)の動作をしてくれるのでPaintイベントが発生します。厳密にPaintイベントがいつ発生するかはOS任せなので、グラフの描画がアニメーションのようなものになる場合は注意が必要です。UpdateメソッドやRefreshメソッドも調べてみてください。

    もうひとつは、B)でBitmapが用意できたら、FormのCreateGraphicsメソッドでGraphicsオブジェクトを生成して、そこにBitmapを描いてやればOKです。ただし、このGraphicsオブジェクトは描画が終わったらDisposeしてください。
    (ホームページを再開しました)
    2010年1月12日 9:45
  • しかしBitmapに描きこむタイミング=”他の画面が重なった時” をイベントの中から探していますが見つけられずにいます。
    ご質問の意図を掴めていないのかもしれませんが、Paint イベントは、他の画面が重なった後、その画面がどけられた時など、画面を再描画する必要がある時に呼び出されます。
    「他の画面が重なった」というピンポイントのイベントはないと思います。

    ところで、Bitmap に一度書き込まないといけないような状況なのでしょうか?
    Paint イベントで得られる e.Graphics に直接書き込むのは速度面などの事情で実現できないのでしょうか?
    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年1月12日 14:05
    モデレータ
  • 外池様

    ご回答をありがとうございます。
    再描画はOSが勝手に処理してくれるとの事なので問題は画像を保存するタイミングです。
    画像は毎秒6ラインほどのスピ-ドで追加されています。ですから保存するタイミングは
    最後まで残しておいて上に別画像が重なった瞬間を保存したいのです。
    そのイベントがないとの事で今回FormイベントのDeactivate を使ってみました。
    ●Deactivateイベントが発生したらBitmapに画面を保存する。 g.CopyFromScreen():g.Dispose()
    ●OSからPaintイベントが来たらBitmapを描画する。 e.Graphics.DrawImage()
    これで静止画像なら問題ないレベルと思います。
    今回は画像が常に追加されているので2つのイベントの時間差部分に画像のない所が
    当然の事ながら発生してしまいました。

    Invalidateメソッドも試してみました。再描画をアプリから指定できるので便利そうです。
    しかし今回は相手の画面の動きが判らないのでOSまかせが簡単です。

    まあ 今回はこれで妥協かな と言うレベルです。
    ありがとうございました。
    2010年1月14日 8:40
  • BufferedGraphics は、今回使用できないのでしょうか。
    • 回答としてマーク uri_uri 2010年1月14日 14:54
    2010年1月14日 9:42
  • 外池です。

    画像が時々刻々更新されるタイプのアプリなんですね。そこ、大事なところなので、最初に仰ってもらわないと・・・(笑)

    私は、時々刻々チャート紙にプロットされていくような感じでグラフを描画するアプリを作ったことがあります。計測器からデータが流れ込んでくるタイプのものと、アプリ自身がちょっとした時間依存のシミュレーターで自らデータを吐き出すタイプのものと・・・。

    いずれも、時々刻々フォームの表示を更新するには、Timerコントロールのイベントを使います。1秒に1回でも、1秒に数回でも、定期的にイベントを発生させられますので、その都度Form.Invalidateをしてやるわけです。

    データの流れ込んでくる早さと、画面の表示を同期させることは、必ずしも必須ではありません。画面に描く画像が大きい場合、早い頻度で更新するとかなりマシンパワーを食います。Bitmapに描画するだけの方がずっと処理は軽いです。

    そんなわけで、データが流れ込んでくるたびにBitmapは更新するものの、そのBitmapをForm上に描画するのは、1秒に1回というのもアリだと思います。
    (ホームページを再開しました)
    2010年1月14日 12:29
  • Michael-k 様

    BufferedGraphics は使った事がありませんでした。今回これで問題を解決できました。
    他の画面の影響を全く受けないBufferに描画するイメ-ジを準備しておいて
    1ライン終了毎にイメ-ジをフォ-ムへ高速転送する方式です。これで6回/秒の更新になるので
    画面の違和感は ほとんどなくなりました。すばらしいです。ありがとうございました。
    2010年1月14日 14:18
  • 外池 様

    BufferedGrafics のやり方を理解してから外池様の この提案を読むと
    考え方は同じなんだなと思います。
    Bitmap(Buffer)に描画すべき画像を用意しておいて区切りのタイミングに
    なったらFormへ転送すると言う事ですね。
    本来あるべき画像を送っているので画面の重なりとかタイミングに無関係になると言う事!!

    私の乏しい経験で”Bitmapに描画”の意味が理解できていませんでした。
    Formと同じようにBitmapへもグラフ描画が可能な事が理解できていませんでした。
    Form<--->Bitmap へのコピ-ばかり考えていたので正解にたどりつけませんでした。
    今は ご提案 よく理解できます。

    ありがとうございました。

    2010年1月14日 14:41