yTakeです。
FMXでTPaintBoxの”OnPaint”でCase文があるとうまく描画されません。
以前、試した時はうまく行った様に思いますが、改めて試すとうまく行きません。
PaintBox1の"ClipChildren"を"True"としています。
テスト1:
procedure TForm3.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var
rectF : TRectF;
str : String;
begin
rectF := TRectF.Create( 50, 50, 200, 200 );
Canvas.Clear( claWhite );
Canvas.DrawRect( rectF, 25, 35, ALLCorners, 1.0 );
rectF := TRectF.Create( 50, 100, 50 + 100, 100 + 25 );
str := 'Hello World!!';
Canvas.Fill.Kind := TBrushKind.Solid;
Canvas.Fill.Color := claGreen;
// Canvas.Clear( claWhite );
Canvas.FillText( rectF, str, False, 1.0, [], TTextAlign.taCenter, TTextAlign.taCenter );
end;
テスト2
procedure TForm3.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var
rectF : TRectF;
str : String;
begin
case status of
1:
begin
rectF := TRectF.Create( 50, 50, 200, 200 );
Canvas.Clear( claWhite );
Canvas.DrawRect( rectF, 25, 35, ALLCorners, 1.0 );
end;
2:
begin
rectF := TRectF.Create( 50, 100, 50 + 100, 100 + 25 );
str := 'Hello World!!';
Canvas.Fill.Kind := TBrushKind.Solid;
Canvas.Fill.Color := claGreen;
// Canvas.Clear( claWhite );
Canvas.FillText( rectF, str, False, 1.0, [], TTextAlign.taCenter, TTextAlign.taCenter );
end;
else
ShowMessage( 'RePaint!' );
end;
end;
procedure TForm3.Button1Click(Sender: TObject);
begin
status := 1 ;
PaintBox1.OnPaint( Sender, PaintBox1.Canvas );
end;
procedure TForm3.Button2Click(Sender: TObject);
begin
status := 2 ;
PaintBox1.OnPaint( Sender, PaintBox1.Canvas );
end;
statusはグローバル変数
としています。
テスト1の結果:
実行すると、矩形が描画され文字列も表示されます。
配置されたPaintBox1の原点(左上)を基点に指定された座標に描画表示されます。
テスト2の結果:
実行すると、起動直後に”RePaint!!”が2回表示されます。もちろん、矩形や文字列データは出ません。
しかしながら、Button1をクリックしても矩形は描画されません。Button2をクリックしても文字列は表示されません。
デバッガで追ってみましたが、正しくCase文を通過し、DrawRect、FillTextを実行しています。が、何も出ません。
Case文を外すと、描画表示されます。
”OnPaint”の中ではCase文は使えないのでしょうか?
根本的に何か間違っているでしょうか?
ご教示頂けると幸いです。
当方、32ビットWindows10+DELPHI XE6+FMX
Windows的にはOnClickなどのイベントで直接描画するのは望ましくない、という話じゃないですか?
(InvalidateRectなどで無効化してWM_PAINTメッセージを生成させ、OnPaintイベントで描画する)
少なくともボタンのクリックイベントで
| PaintBox1.OnPaint( Sender, PaintBox1.Canvas );
というのはちょっと…(FMX内でOnPaintイベントハンドラが呼び出すための前提条件とか無視しちゃっているので)。
通りすがり様
ありがとうございます。
”PaintBox1.OnPaint( Sender, PaintBox1.Canvas );”と言うのは苦肉の策でした。
他のイベント内でPaintBoxへ描画すると座標系が異なりPaintBoxのCanvasへ描画するには、”OnPaint”内で描画する必要があるとの事でした。(或いはSetMatrixを用いるかですが、調べてみた限りではOnPaintで描画するのが一般的の様です)
しかし、”OnPaint”内で描画させても、”OnPaint”自体を呼び出さない限り実行されません。
本例の場合、例えば、Button1イベントでダミーの描画(DrawLine)させる事で”OnPaint”を呼び出すのが、常套手段でしょうか?(しっくり来ませんが)
色々調べて見ていますが、あまり情報がない様な気がしますが、調べ方が悪いでしょうかね。
PaintBox1.Repaint;
編集 削除AAA様
ありがとうございました。
あっさりとうまく行きました。
PaintBox.Canvas以下で探してました。
ただ、この辺りの情報が少ない様に思うのは気のせいでしょうか?
OnPaint自体の使用法はみつかりますが、どの様に呼び出すかは言及されていない例が多いです。(常識過ぎるので、どなたも触れないのでしょうね)
また、ヘルプでもTPaintBox.R〜で探した事はあったのですが、”RotationAngle”と”RotationCenter”しか見当たりません。
コーディングする際に実際に"PaintBox."候補を参照すれば出て来たわけですが、ヘルプを信じて"PaintBox.Canvas."以下ばかりを参照していました。
言い訳になってしまいました。
AAA様、通りすがり様、はじめ皆様ありがとうございました。