Delphi6でImageに画像を再描画する時にちらつくのですが,この原因と,解決策を
教えて頂けると助かります.いろいろ試してはいるのですが,完全にちらつきが無くならず困っております.よろしくお願いします.
>Delphi6でImageに画像を再描画する時にちらつくのですが
TImageの親にもよりますが(つまりコーディングによる),Form1に直接
配置しているのであれば,例えば
Form1.DoubleBuffered:=True;
とすれば効果があるかも知れません.DoubleBufferedプロパティは,
TWinControlから派生したコントロールでないと存在しませんので,
TImageを配置しているコントロールを,ヘルプの[継承]のところから
調べてみて下さい.
どんなコントロールでも基本的にはWindowsに再描画をお願いすることがちらつきの原因になります。
WM_ERASEBKGNDメッセージに0を入れてあげて全部自前で描画させればちらつきは起こりません。
TImageに再描画をお願いすると、画面を一旦背景色で塗りつぶした後、画像を表示させますので、再描画を繰り返す用途には向いていないと思います。
手軽にだったらPaintBoxが良いのではないでしょうか?
Delphi6 の TImage にはバグがあります。
UpDate すると直ります。
それでもちらつきが直らないことが有りえます。
例えば矩形を描き、マウスでその矩形をドラッグ移動させる場合、
(それだけなら問題はないのですが)
スクロールさせるとどうしてもちらつきが出ます。
そのような場合には、
Frm1.DoubleBuffered や ScrollBox1.DoubleBuffered を使うしかありません。
DoubleBuffered は動きが重たくなるので、できれば使わずに済ませたいものです。。
Mr.XRAYさん,メラトニンさん早速のアドバイスありがとうございます.
Imageの配置されていた場所がpanelでしたので
Form1.Panel1.DoubleBuffered:=True;
にした所,完全にちらつきを消す事に成功しました.
本当に助かりました.これで日々の目の疲れから解放されます.
ところで,メラトニンさんに質問なのですが,WM_ERASEBKGNDメッセージ
に0を入れて全部自前で描画する方法は,実際どのようにするとよいのでしょうか?
私はまだDelphiの経験が浅いもので,再描画時にWM_ERASEBKGNDメッセージがWindowsに送られていて,そのメッセージを無視することができればちらつきが
なくなるという情報はあったのですが,やり方が分からず困っておりました.
出来れば教えていただきたいのですが.
すいません.
上の発言者は私です.
Delphi6 TImage のバグは、次の投稿以下で論議されています。
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=080262
sadoyamaさんありがとうございます.
Delphi6のTImage自体にバグがあったんですね・・・.
知りませんでした.
また,Doublebfferedは重くなるという事で,それだとすると
一番最適なのは,WM_ERASEBKGNDメッセージに0を入れるという
方法になるのでしょうか?
WM_ERASEBKGND はウィンドウの背景を書き換える伝令メッセージですので、
たとえば私が例にあげたような場合のちらつきの防止にはまったく無意味です。
したがって、DoubleBuffered を使うしかないのですが、
次のように、その使用を最小限に抑える工夫をしています。
if ScrollBox.VertScrollBar.Visible or
ScrollBox.HorzScrollBar.Visible then
ScrollBox.DoubleBuffered := true
else
ScrollBox.DoubleBuffered := false;
DoubleBufferedを使う時はTRUEにして,使わない時はFALSEにしておくことで
メモリ使用量を軽くするわけですね.
その点は用途に合わせて自分なりに工夫してみたいと思います.
sadoyamaさん,いろいろ教えていただきありがとうございます.
またお世話になる時が来ると思うので,その時はまたアドバイスしていただけ
れば助かります.ありがとうございました.
解決をチェックし忘れました.
とりあえず下記のソースを参考にしてForm1に
Image1を貼り付けてください
画像は適当な大きさのものをあらかじめ貼り付けてください。
Form1をリサイズするとImage1がちらつくことが分かります。
ちらつきが確認できたら
Form1.DoubleBuffered:=True;
にしてみてください、
さらにちらつきがなくなるのを確認したら
Form1.DoubleBuffered:=False;
にしてからコメントアウトを外してください。
とすると、DoubleBufferedを使用しないでちらつかない描画ができます。
ですが、このようなことを行うともはやTImageやTPaintBoxを使用するより自分でコントロールを作成する方が手っ取り早くなります。
>>sadoyama
>>Frm1.DoubleBuffered や ScrollBox1.DoubleBuffered を使うしかありません。
そんな事はありません。ただ簡単では無いだけです。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, jpeg;
type
TForm1 = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private 宣言 }
//procedure WMEraseBkGnd(var Msg: TMessage); message WM_ERASEBKGND;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//コメントを外して比較してください
//その際FormPaintのコメントアウトした一文も外してください
//procedure TForm1.WMEraseBkGnd(var Msg: TMessage);
//begin
// Msg.Result:=0;
//end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Align:=alNone;
Image1.AutoSize:=True;
//切り替えてみてください
DoubleBuffered:=False;
Canvas.Pen.Color:=Canvas.Brush.Color;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
//Canvas.Rectangle(0,0,ClientWidth ,ClientHeight);
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Image1.Left:=ClientWidth - Image1.Width - 50;
Image1.Top :=ClientHeight - Image1.Height - 50;
end;
end.
教えて頂いたソースを参考にプログラムを作成した所,
確かに,DoubleBuffered:=Flase; の状態でちらつきはなくなりました!
いろいろと方法はあるんですね〜.
メモリの面から考えるとこちらの方法をとった方がよさそうですね.
今回,メラトニンさんをはじめ,sadoyamaさん,Mr.XRAYさんからのアドバイスの
おかげで,本当に勉強になりました.
今後,Delphiを使いこなしていく上で,また壁にぶち当たる時がくると思います.
是非その時は,またアドバイスを頂けたら幸いです.
ありがとうございました.
> メラトニン さん
> WM_ERASEBKGNDメッセージに0を入れてあげて全部自前で描画させればちらつきは起こりません。
ここが参考になるでしょう。
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=077643
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=077653
jokさんありがとうございます!!
参考にさせていただきます.
今後ともよろしくお願いします.
ツイート | ![]() |