- 渋木宏明(ひどり)
- ぬし
- 会議室デビュー日: 2004/01/14
- 投稿数: 1155
- お住まい・勤務地: 東京
|
投稿日時: 2005-12-04 12:13
引用: |
|
でも、問題があって、OnPaintの中でBeginInvokeしてEndInvokeで乱数発生させたint[] xを使って牌を表示するようにしているのですが、何が問題かわかってないのですが、このウィンドウがほかのウィンドウの後ろになってしまうと、またアクティブにして前にしたとき、int[] xを使って表示した牌が変わってしまうのです。どうしてでしょうか?
|
OnPaint() で「乱数発生させたint[] xを使って牌を表示するようにしている」からです。
これは、Windows GUI アプリケーションの基本的な仕組みを少し逸脱したスタイルです。
Windows では多数のアプリケーションが共存して動作するため、システムが規定するいくつかの「お約束」に従わなくてはなりません。
OnPaint() は、はじめてウィンドウが表示される時だけではなく、ウィンドウの重なりが変化した時などに「システムから呼び出される」ものです。
なので、OnPaint() では、アプリケーションの「現在の状態に基づいた描画」だけを行うのが基本です。
|
- AKIR
- 常連さん
- 会議室デビュー日: 2005/11/08
- 投稿数: 34
|
投稿日時: 2005-12-04 13:20
マルチスレッドをやめてランダムシャッフルに変えたら、なおりました。でも、14秒たつと、regionで判定して描画した牌が消えてしまいます。TickCountをやめてform.Created==falseとやったら直りました。
|
- AKIR
- 常連さん
- 会議室デビュー日: 2005/11/08
- 投稿数: 34
|
投稿日時: 2005-12-04 16:11
formっていうのはForm1 form = new Form1();です。
|
- AKIR
- 常連さん
- 会議室デビュー日: 2005/11/08
- 投稿数: 34
|
投稿日時: 2005-12-04 19:01
コード: |
| private void Form1_Load(object sender, System.EventArgs e)
{
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseUp);
}
Point MouseUpLocation = new Point();
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
MouseUpLocation.X = e.X;
MouseUpLocation.Y = e.Y;
}
protected override void OnPaint(PaintEventArgs pea)
{
Form1 form1 = new Form1();
Image image = Image.FromFile(@"C:\1.jpg");
Graphics g = pea.Graphics;
if(image!=null) g.DrawImage(image,0,1);
Region region1 = new Region(new Rectangle(0,1,20,30));
while(form1.Created==false)
{
if(region1.IsVisible(MouseUpLocation, pea.Graphics))
{
if(image!=null) g.DrawImage(image,50,0);
goto endloop;
}
Application.DoEvents();
}
endloop:
if(image!=null) g.DrawImage(image,0,50);
}
|
すみませんでした。Form1_LardでMouseEventHandlerのrが抜けてました。
20×30のbmpを用意してくだされば、これでできると思います。
|
- AKIR
- 常連さん
- 会議室デビュー日: 2005/11/08
- 投稿数: 34
|
投稿日時: 2005-12-04 19:07
あと、Form1_Loadはデザインのフォームをダブルクリックしてコードを自動生成させたほうがいいと思います。
|
- ぶさいくろう
- ぬし
- 会議室デビュー日: 2005/11/22
- 投稿数: 1232
- お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
|
投稿日時: 2005-12-04 21:56
引用: |
|
AKIRさんの書き込み (2005-12-04 19:07) より:
あと、Form1_Loadはデザインのフォームをダブルクリックしてコードを自動生成させたほうがいいと思います。
|
素人さんはそれがいいでしょ。
|
- Kazuki
- ぬし
- 会議室デビュー日: 2004/10/13
- 投稿数: 298
|
投稿日時: 2005-12-05 23:28
引用: |
|
AKIRさんの書き込み (2005-12-04 19:07) より:
あと、Form1_Loadはデザインのフォームをダブルクリックしてコードを自動生成させたほうがいいと思います。
|
これがいいと思うなら,MouseUpとかは何故わざわざコードからしてるんですか?
後は,OnPaintをオーバーライドしなくてもPaintっていう名前のイベントが無かったかな?
(どっちでもいいですが)
後,コードについてですが
コード: |
|
Form1 form1 = new Form1(); // <-こいつの存在理由がわからないです
Image image = Image.FromFile(@"C:\1.jpg"); // OnPaintの度に読み込まなくても
// これならコンストラクタでやったほうが
Graphics g = pea.Graphics;
if(image!=null) g.DrawImage(image,0,1); // FromFileってnull返したっけ?
Region region1 = new Region(new Rectangle(0,1,20,30));
while(form1.Created==false) // 要はwhile(true)と同じこと
{
if(region1.IsVisible(MouseUpLocation, pea.Graphics))
{
if(image!=null) g.DrawImage(image,50,0); // nullチェックいるの?
goto endloop; // goto使わなくても書けるような処理なのでわざわざgoto使って複雑度上げないほうがいいと思います。
}
Application.DoEvents();
}
endloop:
if(image!=null) g.DrawImage(image,0,50); // nullチェックいるの?
|
個人的にはOnPaintで描画に関する以外書かないほうがいいと思います。
このロジックなら恐らくOnPaintで無限ループをわざわざ組まなくてもできます。
|
- AKIR
- 常連さん
- 会議室デビュー日: 2005/11/08
- 投稿数: 34
|
投稿日時: 2005-12-06 08:08
Paintイベントハンドラを使いたいならPictureBoxとかに描画しなくちゃいけないので、pictureBox_Paintとかいうふうになります(ってどっかのサイトからですけど)。
while(true)は知りませんでした。それでできました。何がtrueなんでしょうか?教えて頂けるとうれしいです。これだとForm1 form1 = new Form1はいりませんね。
jpgになってましたね。Sample.bmpだったつもりんですが。image!=nullはチェックしたほうがいいですよ。やらないほうがいいですが、nullのチェック無しでそのC:\1.jpgをほかへ移してデバッグしてみてください。僕はbmpでやりましたが、画像が2倍くらい大きくなって描画されます。OSリインストールしたら直りましたけど。
goto書かないでやる方法を教えてほしいです。
Focus();というのがあるみたいですが、これもPictureBoxとかのコントロールを使わなきゃいけないようで、PictureBox使ったほうがいいのかなぁ?
|