以下の TPaintScreen で座標の描写は TPaintScreen 内部で処理し、関数は本体で定義したものを適当な引数で TPaintScreen に渡したいのです。目的はこの2つの処理の裏画面書き込み・表画面転送を同時に行うためです。TPaintScreen.Draw にどういうコードを書けばいいでしょう。
TPaintScreen = class(TPaintBox)
private
procedure FDrawCoordinate(Target: TCanvas);//座標
public
Func: Pointer;
OffBmp: TBitmap;
procedure Draw;
・・・・・・
end;
constructor TPaintScreen.Create(AOwner: TComponent; Func: Pointer);
begin
OffBmp := TBitmap.Create; //オフスクリーン
inherited Create(AOwner);
end;
procedure TPaintScreen.FDrawFunction(Target: TCanvas);
begin
end;
procedure TPaintScreen.Draw;
begin
FDrawCoordinate(OffBmp.Canvas);//座標
{ ここで以下のようにすると「演算子まだはセミコロンが必要」のコンパイルエラー発生
Func(OffBmp);
この程度の簡潔なコードで TForm1.FDrawSinX を処理する方法はないものか}
Canvas.Draw(0, 0, OffBmp);
end;
// +----------------- Form1 ------------------+
procedure TForm1.FormCreate(Sender: TObject);
begin
PaintScreen1 := TPaintScreen.Create(Form1);
PaintScreen1.Func := Nil;
・・・・・・
end;
procedure TForm1.FDrawSinX(Target: TPaintScreen);
begin
with Target.OffBmp.Canvas do
・・・・・・
//ここでTarget.Canvas.Draw(0, 0, Target.OffBmp); で表画面に転送してもちらつく
end;
procedure TForm1.FPutScreen;
begin
PaintScreen1.Func := TForm1.FDrawSinX;
PaintScreen1.Draw;
end;
> Func(OffBmp);
これはミス。しかしここをFunc(Self);としてもだめだろうし・・・。
「メソッドポインタ」
type
TPaintScreen=class;
TFunc = procedure(Target: TPaintScreen) of object;
TPaintScreen = class(TPaintBox)
public
Func: TFunc;
end;
procedure TForm1.FPutScreen;
begin
PaintScreen1.Func := FDrawSinX;
end;
こんな感じ?
どうせならイベントにしたほうが・・・・
TDrawSinX = procedure (Sender: TBitmap) of object;
TPaintScreen = class(TPaintBox)
private
FDrawSinX: TDrawSinX;
OffBmp: TBitmap;
public
procedure Draw;
procedure DrawSinX(ABitmap: TBitmap);
published
property OnDrawSinX: TDrawSinX read FDrawSinX write FDrawSinX;
end;
procedure TPaintScreen.Draw;
begin
DrawSinX(OffBmp);
end;
procedure TPaintScreen.DrawSinX(ABitmap: TBitmap);
begin
if Assigned(OnDrawSinX) = True then OnDrawSinX(ABitmap);
end;
レスありがとうございます。まずofZ さんの方法でやってみましたが、関数は描かれません。
TPaintScreen 内部でFuncを処理する必要はないのでしょうか?
KHE00221 さんの方はイベントの代入でコンパイルエラーが出ます。
procedure TForm1.FormCreate(Sender: TObject);
begin
PaintScreen1 := TPaintScreen.Create(Form1);
with PaintScreen1 do
begin
OnPaint := PaintScreen1Paint;//イベントを代入
・・・・・・・・
OnDrawSinX := PaintScreen1DrawSinX; //ここでTBitmapとTObjectの互換エラー発生
end;
end;
procedure TForm1.PaintScreen1DrawSinX(Sender: TObject);
var
Ex,Ey: Extended;
begin
with PaintScreen1 do
OffBmp.Canvas.・・・・;
end;
ちょい修正
TDrawSinX = procedure (Sender: TObject; ABitmap: TBitmap) of object;
TPaintScreen = class(TPaintBox)
private
FDrawSinX: TDrawSinX;
OffBmp: TBitmap;
public
procedure Draw;
procedure DrawSinX(ABitmap: TBitmap);
published
property OnDrawSinX: TDrawSinX read FDrawSinX write FDrawSinX;
end;
procedure TPaintScreen.Draw;
begin
DrawSinX(OffBmp);
end;
procedure TPaintScreen.DrawSinX(ABitmap: TBitmap);
begin
if Assigned(OnDrawSinX) = True then OnDrawSinX(Self,ABitmap);
end;
に変更して
procedure TForm1.PaintScreen1DrawSinX(Sender: TObject; ABitmap: TBitmap);
var
Ex,Ey: Extended;
begin
with ABitmap do
Canvas.・・・・;
イベントにしてるからオブジェクトインスペクターから設定できるけど・・・
動的に作ってるのかな?
> KHE00221 さん
ありがとうございました。無事動きましたです。
> 動的に作ってるのかな?
そのとおりです。昔から自作の使い捨てコンポはほとんど動的に使用していました。人に使ってもらうようなものは作れないので TCustomXXX から継承したこともほとんどありません(笑)。というかコンポ作成の方法をほとんど忘れています。
実は10年ぶりくらいにDelphiで遊びだしたのですが(今だにDelphi5です)、10年ほど前に自分が作ったコードすら、コメントを書いているにもなかなかわからないような状態です。
このようなサイトはほんとうにありがたいですね。
ツイート | ![]() |