🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: japan.comp.lang.delphi
Article #11

Re: 画面モード切替後のグラフィックパフォーマンスの低下

#11
From: K.Takaoka
Date: Mon, 27 Dec 1999 00:00
119 lines
5137 bytes
える@海豚ぞな

林 知紀 wrote:
> しかし、フォームをドラッグするなどOnPaintイベントが発生すると
> 画像が消えてしまいます。
> 不思議なのはもう一度同じコードを実行した後は
> 画面の端や別のウインドウ等で隠された部分だけしか消えません。

これは前回書いたことと同じことになるので略します。

> 以上の現象からOnPaintイベントは
> OSが「君の窓が動いたり隠れていた場所が見えたりしたよ」と
> アプリケーションに通知してきたのを受けて
> 発生するイベントではないかと思ったのですが
> 間違った理解なのでしょうか?

間違ってはいないと思いますが、ウィンドウが移動したり隠れていた
のが見えた結果として、見えなかったところが見えるようになり、画
面に表示するための情報を得たいという意味で Paint (OnPaint) が
呼び出されます。

言い換えれば、Paint(OnPaint) は、呼び出されたときに、その時点で
の「最新の情報」を漏らさず Canvas に書かなければなりません。

> ただ、LineToで直接PaintBox1.Canvasに書き込んだり

といった、書きこんだ情報を、すべて OnPaint で再描画しないと、

> フォームが動くなどOnPaintイベントが発生するたびに
> 画面がBitmapの内容に戻ってしまう

という状態になります。
これは Windows の描画アルゴリズムが、こうなっているための仕様です。

TImage や TWinControl.DoubleBuffered はこれらを Delphi/VCL が自動化
してくれています。

> ので
> Bitmap.Assign(Bitmap2);
> PaintBox1.Canvas.Draw(0,0,Bitmap);
> と若干冗長なコードが必要なのが面倒くさいところです。

これはちょっと意味がわからないです. 何をしたいのでしょうか ?
具体的に、どういうコードでは、どうダメだから、上記のように書くと
どう良くなるのかを書いていただけると、意味が取りやすいです (^^;

xxxxxxxxxxx;

と書いただけでは画面表示が○○となってしまうけど、

Bitmap.Assign(Bitmap2);
PaintBox1.Canvas.Draw(0,0,Bitmap);

とすれば、ちゃんと動作する...といった具合に...

> 最終的にVGAサイズのフルスクリーンにしようと思ってるので
> OnPaintイベントはなかなか発生しないんじゃないかと
> 思っています。

OnPaint は、その Form なり PaintBox なりの一部分でも再描画する
必要が出来たら呼び出されます。

逆にいえば、部分的に書き換えた場合には現在内容を描画するために
Paint を使えますし、使うようにすると描画が変になることはないは
ずです。

もう、分かっておられるような気がしますが、TButton と TPaintBox
が1つづつ有る状態で、ボタンを押すと TPaintBox の上に線が出るよ
うな例では

var
  drawLine: Boolean;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // ボタンが押された

{ // ここで書くこともできるが、書かないで
  with PaintBox1 do
  begin
    Canvas.MoveTo(0, 0);
    Canvas.LineTo(Width, Height);
  end;
}

  // 現在、線がある状態であることを記録するだけにする、そして
  drawLine := true;

  // PaintBox1 の現在内容は線がないという古い状態(=無効になった)
  // なので最新の状態にしたい、そこで現在内容は無効であることを
  // Windows に通知する
  PaintBox1.Invalidate;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  // 再描画が必要になったら呼び出される
  // ここは PaintBox1 の Paint イベントなので、現在の PaintBox1
  // の状態を調べて、最新の内容を残さず描画する必要がある

  // 線が書かれている状態であれば書く
  if (drawLine) then
  begin
    with PaintBox1 do
    begin
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(Width, Height);
    end;
  end;
end;

のような感じになります。

オフスクリーンとして TBitmap を利用しているならば、Button1Click
などでは TBitmap.Canvas に変更を行って、PaintBox1 を Invalidate
するという手順にし、PaintBox1 では最新の情報を保持している TBitmap
を draw するだけということになります。

# そして、それを自動でやっているのが TImage です (^^;
Technical Details
Message-ID: <3866712B.F98B267D@din.or.jp>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail
References: <83ou3d$jvv$1@nw041.infoweb.ne.jp> <3860CAFB.E16988D7@po.teleway.ne.jp> <83u3iq$i92$1@nw041.infoweb.ne.jp> <842u63$fpk@www.net0726.or.jp> <8451vt$ojp$1@nw042.infoweb.ne.jp> <38661455.CECA03D4@din.or.jp> <845ji4$1l$1@nw042.infoweb.ne.jp>

Show Full Headers
Complete Article Headers
X-Google-Language: Japanese,JIS
X-Google-Thread: 110a07,f2bd283c630b1b34
X-Google-Attributes: gid110a07,public
X-Google-Thread: fecfa,f2bd283c630b1b34
X-Google-Attributes: gidfecfa,public
X-Google-Thread: feb2e,f2bd283c630b1b34
X-Google-Attributes: gidfeb2e,public
From: "K.Takaoka" <saepro@din.or.jp>
Subject: Re: 画面モード切替後のグラフィックパフォーマンスの低下
Date: 1999/12/27
Message-ID: <3866712B.F98B267D@din.or.jp>
X-Deja-AN: 565088623
Content-Transfer-Encoding: 7bit
References: <83ou3d$jvv$1@nw041.infoweb.ne.jp> <3860CAFB.E16988D7@po.teleway.ne.jp> <83u3iq$i92$1@nw041.infoweb.ne.jp> <842u63$fpk@www.net0726.or.jp> <8451vt$ojp$1@nw042.infoweb.ne.jp> <38661455.CECA03D4@din.or.jp> <845ji4$1l$1@nw042.infoweb.ne.jp>
X-Accept-Language: ja,en
Content-Type: text/plain; charset=iso-2022-jp
Organization: DOLPHIN INTERNET, Tokyo, Japan.
Mime-Version: 1.0
Newsgroups: japan.comp.lang.delphi,fj.comp.lang.pascal,fj.os.ms-windows.programming