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

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

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

Re[9]: 画像が消えてしましいます。( ; ; )


(過去ログ 47 を表示中)

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

■25428 / inTopicNo.1)  画像が消えてしましいます。( ; ; )
  
□投稿者/ 裕猫 (42回)-(2008/09/19(Fri) 11:42:49)

分類:[C#] 

動作テストしていて気づきました。別のwindowが重なるとそのwindowが消えたところのグラフィックが消えてしまいます。ダブルバッファリングを使うと瞬間表示して画像が消えてしまいます。ResizeRedrawなど設定してみましたが、改善できません。原因知っている方、お助けください。以下にコード表記しておきます。

        public void MTM()
        {
//            this.DoubleBuffered = true;
            IllustClass.Paint(Haikei, Hito, X, CreateGraphics());
//            Invalidate();
//            this.SetStyle(ControlStyles.ResizeRedraw, true);
            OnseiClass.Koe(Kotoba);
        }

↑をform1にて呼び出します。//をとるとダブルバッファリング動きますが、瞬間表示してボタンなどのコントロールが出ると消えてしまいます。グラフィックはIllustClassを作ってform外より呼び出します。この状態だと表示はしていますが、別のwindowが重なるとその部分のグラフィックが消えてしまいます。

    public static class IllustClass
    {
        public static void Paint(string usiro, string hito, int Iti, Graphics g)
        {
            Bitmap Haikei = new Bitmap(usiro);
            Bitmap Mask = new Bitmap(hito);
            Bitmap Kyara = new Bitmap(hito);

            Rectangle Kage = new Rectangle(Mask.Width / 2, 0, Mask.Width, Mask.Height);
            Rectangle HKage = new Rectangle(0, 0, Kyara.Width / 2 - 1, Kyara.Height);

            Mask.MakeTransparent(System.Drawing.Color.White);
            Kyara.MakeTransparent(System.Drawing.Color.Black);

            g.DrawImage(Haikei, 0, 0);
            g.DrawImage(Mask, Iti, 511 - Mask.Height, Kage, GraphicsUnit.Pixel);
            g.DrawImage(Kyara, Iti, 511 - Kyara.Height, HKage, GraphicsUnit.Pixel);

            Haikei.Dispose();
            Mask.Dispose();
            Kyara.Dispose();
        }
    }
以上よろしくお願いいたします。

引用返信 編集キー/
■25431 / inTopicNo.2)  Re[1]: 画像が消えてしましいます。( ; ; )
□投稿者/ よねKEN (191回)-(2008/09/19(Fri) 11:51:30)
Paintイベントで描画していないからです。
Paintイベントの引数eのGraphicsプロパティのオブジェクトに対して処理しましょう。

> IllustClass.Paint(Haikei, Hito, X, CreateGraphics());

CreateGraphicsで作成したGraphicsオブジェクトに描画しても1回きりですので。


http://bbs.wankuma.com/index.cgi?mode=al2&namber=25027
No25036の私のレスが役に立つかもしれません。

引用返信 編集キー/
■25447 / inTopicNo.3)  Re[2]: 画像が消えてしましいます。( ; ; )
□投稿者/ PATIO (115回)-(2008/09/19(Fri) 14:06:36)
2008/09/19(Fri) 14:10:14 編集(投稿者)
2008/09/19(Fri) 14:09:44 編集(投稿者)
2008/09/19(Fri) 14:07:24 編集(投稿者)

既に よねKENさんがその物ズバリの内容を書かれていますが、

Windowsのイベントドリブンの考え方をしっかり理解しておくと言語を変えても
応用が利きますからお勧めします。

Windowsでの画面の書き換えは、Paintイベントがトリガーになります。
再描画処理がない(Paintイベントの中に処理がない)場合、他の画面で上書きされない
限りは前の描画結果が残っていますが、それは黒板に書いた絵みたいな物で
他の描画で上書きされるまでの命です。
各ウインドウは常に全てを再描画しているわけではなくて
他の画面に隠れた部分に関しては再度見えるようになるまでは描画対象から外されます。
なので、再び見えるようになったタイミングでその部分を再描画する必要が
あるわけです。OSが再描画を指示するとPaintイベントが来ますから
このイベントが来た時に自画面のすべてを再描画可能な状態にしておく事で
画面を常に最新の状態にする事が出来ます。

例えば、画面上の描画の内、ボタンのクリックイベントに対応する処理に
しかない描画処理はボタンをクリックすると描画されますが、
他のウインドウが重なってしまうとその処理は呼ばれないので消えてしまいます。
Paintイベントに対応する処理の中で行なわれている描画処理だけが毎回必ず動くわけです。
描画処理その物は別の関数やクラスにしてしまっても良いのですが、
描画を実行するために呼び出す処理はPaintイベントに対応した処理の中にないと駄目です。

Windows上の描画に関しては言語が変わっても考え方は同じなので覚えておいた方がよいです。

引用返信 編集キー/
■25452 / inTopicNo.4)  Re[3]: 画像が消えてしましいます。( ; ; )
□投稿者/ 裕猫 (43回)-(2008/09/19(Fri) 15:21:06)
No25447 (PATIO さん) に返信
よねKEN様 PATIO様返信ありがとうございます。ペイントイベントを使用しないのが原因というのはわかりました。最初はPaintEventArg eで作ろうとしてたのですが、引数が渡せなかったり、Graphic.Imageが使えなくなったりと、悪戦苦闘の末こんなコードになってしまいました。これにPaintEventArgをつけるとエラーになってしまうし・・・どこかこのようにグラフィック処理を別クラスにしてペイントイベントを処理するのに参考になるサイトはご存知ありませんでしょうか?いろいろ探しているのですが、まだたどり着けません。ご存知でしたら教えていただきたいのですが。よろしくお願いいたします。
引用返信 編集キー/
■25454 / inTopicNo.5)  Re[4]: 画像が消えてしましいます。( ; ; )
□投稿者/ のん (5回)-(2008/09/19(Fri) 15:35:59)
のん さんの Web サイト
No25452 (裕猫 さん) に返信
> ■No25447 (PATIO さん) に返信
> よねKEN様 PATIO様返信ありがとうございます。ペイントイベントを使用しないのが原因というのはわかりました。最初はPaintEventArg eで作ろうとしてたのですが、引数が渡せなかったり、Graphic.Imageが使えなくなったりと、悪戦苦闘の末こんなコードになってしまいました。これにPaintEventArgをつけるとエラーになってしまうし・・・どこかこのようにグラフィック処理を別クラスにしてペイントイベントを処理するのに参考になるサイトはご存知ありませんでしょうか?いろいろ探しているのですが、まだたどり着けません。ご存知でしたら教えていただきたいのですが。よろしくお願いいたします。

お世話になります。
これちょっと参考になるような気がします。
http://www.atmarkit.co.jp/fdotnet/dotnettips/458picboxdraw/picboxdraw.html
引用返信 編集キー/
■25456 / inTopicNo.6)  Re[4]: 画像が消えてしましいます。( ; ; )
□投稿者/ επιστημη (1328回)-(2008/09/19(Fri) 15:43:58)
επιστημη さんの Web サイト
> グラフィック処理を別クラスにしてペイントイベントを処理するのに参考になるサイトはご存知ありませんでしょうか?

...そもそもペイントイベントを捕まえていますか?
ペイントイベントに対するハンドラ・メソッドを正しく定義していますか?

引用返信 編集キー/
■25458 / inTopicNo.7)  Re[5]: 画像が消えてしましいます。( ; ; )
□投稿者/ 裕猫 (44回)-(2008/09/19(Fri) 16:15:58)
No25454 (のん さん) に返信
> http://www.atmarkit.co.jp/fdotnet/dotnettips/458picboxdraw/picboxdraw.html
ありがとうございます。見てみました。でもまだ解決していません。ありがとうございました。
引用返信 編集キー/
■25459 / inTopicNo.8)  Re[5]: 画像が消えてしましいます。( ; ; )
□投稿者/ 裕猫 (45回)-(2008/09/19(Fri) 16:25:05)
No25456 (επιστημη さん) に返信
> ...そもそもペイントイベントを捕まえていますか?
理解がしっかりしていないと思います。たとえば、ペイントイベントはフォーム以外の関係ないクラスで定義できるのか?と最近疑問に思ったりしていますから。

> ペイントイベントに対するハンドラ・メソッドを正しく定義していますか?
これも自分で定義するとうまくいったりいかなかったり、という状況です。細かい注意点がわかっていないためとは思っています。サンプルの説明では分かっているのですが応用がうまくいきません。
引用返信 編集キー/
■25460 / inTopicNo.9)  Re[6]: 画像が消えてしましいます。( ; ; )
□投稿者/ επιστημη (1329回)-(2008/09/19(Fri) 16:28:00)
επιστημη さんの Web サイト
>>...そもそもペイントイベントを捕まえていますか?
> 理解がしっかりしていないと思います。たとえば、ペイントイベントはフォーム以外の関係ないクラスで定義できるのか?と最近疑問に思ったりしていますから。

そぢゃなくてぇ...
フォームのイベントハンドラがちゃんと動いているなら、
そのハンドラの処理内で外部の描画ルーチンを呼べばいぃやないの。

> サンプルの説明では分かっているのですが応用がうまくいきません。

応用がうまくいかないのは基礎ができてないからです。

引用返信 編集キー/
■25461 / inTopicNo.10)  Re[7]: 画像が消えてしましいます。( ; ; )
□投稿者/ PATIO (117回)-(2008/09/19(Fri) 16:51:43)
No25460 (επιστημη さん) に返信
> そぢゃなくてぇ...
> フォームのイベントハンドラがちゃんと動いているなら、
> そのハンドラの処理内で外部の描画ルーチンを呼べばいぃやないの。

私が書いていた
「描画処理その物は別の関数やクラスにしてしまっても良いのですが、
描画を実行するために呼び出す処理はPaintイベントに対応した処理の中にないと駄目です。」
が、そのまんま同じ意味です。

描画処理自体は即時描画をしたい場合等々の関係で別にまとめてしまうとか
やっても一向に構わないのですけれど、少なくともイベントハンドラから呼び出されていないと
OSからの再描画要求に答えられないので他の画面がのっかると消えてしまうのです。
で、通常はイベントハンドラに渡って来たGraphicを描画用の関数なり、クラスに渡せば良いだけなので
それほど難しい処理ではないはずなんですけれど、うーむ。
何か基本的な部分の理屈がうまく理解できていない様な気がします。

引用返信 編集キー/
■25462 / inTopicNo.11)  Re[6]: 画像が消えてしましいます。( ; ; )
□投稿者/ PATIO (118回)-(2008/09/19(Fri) 17:13:05)
No25459 (裕猫 さん) に返信
> 理解がしっかりしていないと思います。たとえば、ペイントイベントはフォーム以外の関係ないクラスで定義できるのか?
> と最近疑問に思ったりしていますから。

> これも自分で定義するとうまくいったりいかなかったり、という状況です。細かい注意点がわかっていないためとは思っています。
> サンプルの説明では分かっているのですが応用がうまくいきません。

基本的にイベントハンドラと呼ばれるものその物に関してはイベント受け取るクラスで無いと駄目だと思いますよ。
まあ、厳密に言い出したら色々有りそうですが、基本的な意識としてはフォームのようにイベント受け取る事が出来るクラスに
作ると思います。イベントハンドラその物はフォームのようなイベントを受け取るクラスに合って、そこから呼び出される描画処理は
イベントを受け取らないクラスでも良いと思います。
うまく行かなかったと書かれていますけれど、using文が足りないとかそういう問題もあったのではと思っています。

もしそうだとすると、単純なコンソールアプリで複数のクラスに分割して作ったりして基本的な部分を
確認した方が良いのではと思います。恐らく画面周りがどうとかと言う話ではなくてC#の基本的な部分の話に
なりそうな気がするので。
あらかた雛形で用意されているような環境だとこの辺が身につかない気がしますし。

引用返信 編集キー/
■25463 / inTopicNo.12)  Re[7]: 画像が消えてしましいます。( ; ; )
□投稿者/ Tram (4回)-(2008/09/19(Fri) 17:37:25)
既に皆さんが詳細に解説されている通りで、難しい事はないと思うんですが。。
うーん、FormのPaintイベントでIllustClass.Paint()を呼んであげるだけですよね

private void Form1_Paint(object sender, PaintEventArgs e)
{
    IllustClass.Paint(Haikei, Hito, X, e.Graphics);
}

もしかして、e.Graphics ではなく、CreateGraphics()で Graphics を渡しているとか?

引用返信 編集キー/
■25495 / inTopicNo.13)  Re[8]: 画像が消えてしましいます。( ; ; )
□投稿者/ 裕猫 (46回)-(2008/09/20(Sat) 12:43:10)
Tram様
PATIO様
επιστημη様
返信遅れてすみません。
昨日は本業があわただしくて(社内のパソコン2台壊れて修理 + 業務システムの一部プログラムの自動化)あのあとアクセスできませんでした。帰社後は裏のお仕事してアクセスできたのが今朝。初めて自宅パソコンからアクセスしたら書き込みができなくて遅くなってしまいました。本当にごめんなさい。

>επιστημη様
>フォームのイベントハンドラがちゃんと動いているなら、
>そのハンドラの処理内で外部の描画ルーチンを呼べばいぃやないの。
以前フォームでイベントハンドラ設定して使おうとしたら、引数が合わないとか、呼び出そうとしたらオーバーロードがどうとかエラーが出るので以後設定してないです。

PATIO様
>描画処理その物は別の関数やクラスにしてしまっても良いのですが、
>描画を実行するために呼び出す処理はPaintイベントに対応した処理の中にないと駄目です。

>描画処理自体は即時描画をしたい場合等々の関係で別にまとめてしまうとか
>やっても一向に構わないのですけれど、少なくともイベントハンドラから呼び出されていないと ←これが原因だということが皆さんの指摘でわかりました。
>OSからの再描画要求に答えられないので他の画面がのっかると消えてしまうのです。
>で、通常はイベントハンドラに渡って来たGraphicを描画用の関数なり、クラスに渡せば良いだけなので
>それほど難しい処理ではないはずなんですけれど、うーむ。     ←ここがうまくいってないです。
>何か基本的な部分の理屈がうまく理解できていない様な気がします。

>基本的にイベントハンドラと呼ばれるものその物に関してはイベント受け取るクラスで無いと駄目だと思いますよ。
>まあ、厳密に言い出したら色々有りそうですが、基本的な意識としてはフォームのようにイベント受け取る事が出来るクラスに
>作ると思います。イベントハンドラその物はフォームのようなイベントを受け取るクラスに合って、そこから呼び出される描画処理は
↑わかりました。こういうことを記述しているところがないんですよね。(気づいていないだけかな?)おかげさまでもやもやしていたところがすっきりした感じです。

Tram様
>private void Form1_Paint(object sender, PaintEventArgs e)
>{
> IllustClass.Paint(Haikei, Hito, X, e.Graphics);
>}
この後の呼び出しで失敗してこれをはずしてしまいました。(^^;)

ということで皆さんのおかげで原因は理解しました。もう一度ハンドラの呼び出しを使う方法で組みなおしてやってみます。ありがとうございました。
解決済み
引用返信 編集キー/
■25542 / inTopicNo.14)  Re[9]: 画像が消えてしましいます。( ; ; )
□投稿者/ 裕猫 (47回)-(2008/09/22(Mon) 10:14:14)
結果報告
皆様お世話になりました。思った通りの動作できました。答えとしてTramさんの
private void Form1_Paint(object sender, PaintEventArgs e)
{
IllustClass.Paint(Haikei, Hito, X, e.Graphics);
}
がそのまま答えでした。form1の中でグラフィックを何度も書き換える必要があったので、その都度ペイントイベントを実行しなければならないと思い、ペイントイベントをbutton1_clickやbutton2_clickで呼び出そうとしたのが間違いでした。何もしなくても引数の値を変えてやればペイントイベント呼び出さなくてもその都度勝手に変えてくれるんですね。(暴33);知りませんでした(^^;)
という皆様からするとアホみたいな勘違いが原因でした。ありがとうございました。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -