AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
DelphiXE3 [FMX] ペイントボックス(PaintBox)2013/12/27
 
前回は [Shapes]内の「画像」(Image)について見てみました。
今回は、同じく[Shapes]内の「ペイントボックス」(PaintBox)について見てみます。【DelphiXE3・VCLの記事】【Delphi2010の記事】
 
 
[Shapes]内
FMX
 
ヘルプより。
TPaintBox は、アプリケーションで画像のレンダリングに使用できるキャンバスとなる 2D 画像コンポーネントを定義します。TControl を継承しており、コントロールを作成するためのスタイルで使用できます。
 
TImage では、ファイルに保存されている画像を表示しますが、それとは異なり、TPaintBox では、アプリケーション側でキャンバスに直接画像を描画する必要があります。OnPaint イベントのイベント ハンドラを使用すると、ペイント ボックスの描画面である FMX.Types.TCanvas 上に描画することができます。
 

 

 
 
というわけで、お絵描きプログラムやCADプログラムを作る際には、おなじみのペイントボックスです。取り敢えず、Delphi2010の記事と同様のテストプログラムを記述してみます。ボタンを1つ配置して、そのクリックイベントハンドラを記述します。

procedure TForm1.Button1Click(Sender: TObject);
var
 i : integer ;
begin
 with PaintBox1 do begin
  Canvas.BeginScene ;
  Canvas.Stroke.Kind := TBrushKind.bkSolid ;
  for i:=0 to Round(Height) do begin
   Canvas.Stroke.Color := $FF000000 + dword(i) ;
   Canvas.DrawLine(PointF(0,i),PointF(Width,i),1.0) ;
  end;
  Canvas.EndScene ;
 end;
end;
保存・コンパイル・実行をしてみます。



 
VCLでの TColor値と FMXでの TAlphaColor値は、値の持ち方が違いますので、赤色系ではなく、青色系になっています。ダミーで付けたメインメニューを操作しても、別段何もせずとも、画面は乱れず現状をキープしているようです。他のアプリケーションで画面を隠しても、画面は乱れません。となると、ペイントボックスの OnPaintイベントは発動しているのでしょうか?確認してみます。
procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
 ShowMessage('再描画');
end;
実行すると、メッセージは最初に2回表示されますが、メインメニューで隠しても、他のアプリケーションで画面を隠しても、メッセージは表示されません。という事は、OnPaintイベントハンドラでの画面の再描画は不必要、という事になりますね。
 
OnPaintイベントハンドラを記述してしまうと、ペイントボックスがリサイズ出来る状況になると、悲惨な状況に陥りそうです。ペイントボックスの Alignプロパティを alLeft にして画面をリサイズしようとすると、画面を1ドット動かそうとするたびにOnPaintイベントが発動されてしまいます。それでは、OnResizeイベントハンドラを記述した場合はどうなるのでしょうか? 同じく、画面を1ドット動かそうとするたびにイベントが発動されてしまいます。フォーム画面の OnPaint、OnResizeも同様な様子です(フォーム上に配置したボタンにマウスを合わせてボタンがハイライトされるだけでOnPaintが発動してしまうので更に使い難いと思われます)。ですので、他の何らかの手法を考えた方がよさそうです。
 
それはさておき。
 
ペイントボックス PaintBox には、他のビジュアルコンポーネントにもある Canvas プロパティがあり、これに対して作図を行う、という事を行います。Canvasを操作する最初に BeginSceneメソッドを、最後に EndSceneメソッドを実行する必要があります。これは Direct2D と同じ感じなのですぐに分かると思います。Canvas には VCLとは名前や機能内容は多少違いますが、同じような、Strokeプロパティ(従来のペン)、Fillプロパティ(従来のブラシ)、Fontプロパティがあります。
実際に図形を作図するメソッドとしては、下記のようなものがあります。VCLでのWindowsGDIとは異なりますが、GDI+やDirect2D を使っていれば内容はすぐに分かると思います。
AfterConstruction public
 Owner のインターフェースへの参照を取得します。
Assign public
 ほかの類似オブジェクトの内容をコピーします。
BeforeDestruction public
 最初のデストラクタが実行される前に応答します。
BeginScene public
 描画が開始されたことを、TCanvas オブジェクトに通知します。
ClassInfo public
 オブジェクト型の実行時型情報(RTTI)テーブルのポインタを返します。
ClassName public
 引数で渡される変数の型ではなくオブジェクトインスタンスの型を示す文字列を返します。
ClassNameIs public
 オブジェクトが指定の型かどうかを示します。
ClassParent public
 1 つ上位のクラスの型を返します。
ClassType public
 オブジェクトのクラスへのクラス参照を返します。
CleanupInstance public
 クラス内の長い文字列とバリアントとインターフェース変数に対する終了処理を実行します。
Clear public
 TCanvas オブジェクトの表面のクリアします。
ClearRect public
 TCanvas オブジェクトから、四角形の領域をクリアします。
Create public
DefaultHandler public
 メッセージレコードを処理するメソッドのインターフェースを提供します。
Destroy public
 現在の TCanvas とそのコンポーネントを破壊し、メモリも解放します。
Dispatch public
 Message パラメータの内容に基づいてオブジェクトのメッセージ処理メソッドを呼び出します。
DrawArc public
 TCanvas 上の楕円形の曲線の一部として、弧を描画します。
DrawBitmap public
 TBitmap イメージから指定された領域を、イメージが TCanvas の指定された領域へスケーリングされた後に描画します。
DrawDashRect public
DrawEllipse public
 四角形の境界線で定義される楕円を、現在の TCanvas 上に描画します。
DrawLine public
 2 つの点で定義される線を、現在の TCanvas 上に描画します。
DrawPath public
 path を、現在の TCanvas 上に描画します。
DrawPolygon public
 多角形 を、現在の TCanvas 上に描画します。
DrawRect public
 カスタマイズされた角のrectangleを、現在の TCanvas に描画します。
DrawRectSides public
 カスタマイズされた角を持つrectangleの指定された辺を、現在の TCanvas に描画します。
EndScene public
 描画完了したことを TCanvas オブジェクトに通知します。
Equals public
 現在のインスタンスとパラメータが等しいかどうかを調べます。
ExcludeClipRect public
 TCanvas のクリップ領域から四角形領域を除外します。
FieldAddress public
 パブリッシュオブジェクト項目のアドレスを返します。
FillArc public
 TCanvas 上の弧を塗りつぶします。
FillEllipse public
 現在の TCanvas 上に、四角形の境界線で定義される楕円を塗りつぶして描画します。
FillPath public
 現在の TCanvas 上に、パスを塗りつぶし、表示します。
FillPolygon public
 現在の TCanvas 上に、多角形を塗りつぶし、表示します。
FillRect public
 カスタマイズされた角の rectangle を塗りつぶし、現在の TCanvas に表示します。
FillText public
 テキスト文字列を、現在の TCanvas の指定された四角形領域上に表示します。
FinalizeBitmap public
FlushBufferRect public
 カラー データのビット ブロックを、指定されたデバイス コンテキストにコピーします。
Free public
 オブジェクトを破棄し,必要ならば関連付けられているメモリを解放します。
FreeInstance public
 NewInstance メソッドの前回の呼び出しによって割り当てられたメモリを解除します。
GetHashCode public
 ハッシュ コードを表す整数を返します。
GetInterface public
 指定したインターフェースを取り出します。
GetInterfaceEntry public
 クラス内で実現された特定のインターフェースのエントリを返します。
GetInterfaceTable public
 指定したクラスで実装されているすべてのインターフェースが入った構造体のポインタを返します。
GetNamePath public
 オブジェクトインスペクタに表示されるオブジェクト名を返します。
InheritsFrom public
 2 つのオブジェクト型の関係を調べます。
InitializeBitmap public
InitInstance public
 新しく割り当てられたオブジェクトインスタンスをすべて 0 に初期化し,インスタンスの仮想メソッドテーブルポインタを初期化します。
InstanceSize public
 オブジェクト型の各インスタンスのサイズをバイト数で返します。
IntersectClipRect public
 TCanvas の現在のクリップ領域と四角形が、交差することにより描画領域を定義します。
LoadFontFromStream public
 フォント ファミリをストリームからロードします。
MapBitmap public
MeasureLines public
 指定された四角形に囲まれ、指定されたプロパティを持つ特定のテキストの、行を測定します。
MeasureText public
 指定された揃え位置、フラグ、現在のフォントで表示される、テキスト文字列が TCanvas 上で占める領域を測ります。
MethodAddress public
 名前を指定すると、クラス メソッドのアドレスを返します。
MethodName public
 アドレスを指定すると、クラス メソッドの名前を返します。
MultiplyMatrix public
 Matrix プロパティを拡大させます。
NewInstance public
 オブジェクト型のインスタンスにメモリを割り当て,その新しいインスタンスを指すポインタを返します。
operator () public
PtInPath public
 特定の頂点が、TPathData に属しているかどうかを確認します。
QualifiedClassName public
 クラスの修飾名を返します。
QueryInterface public
 指定されたインターフェースをオブジェクトがサポートしている場合,そのインターフェースへの参照を返します。
ResizeBuffer public
 バッファをサイズ変更します。
RestoreState public
 TCanvas の描画と設定済みのプロパティを、保存されている状態まで復元します。
SafeCallException public
 safecall 呼び出し規約を使って宣言されたメソッド内での例外を処理します。
SaveState public
 TCanvas の現在の描画と設定済みのプロパティを保存します。
SetCustomDash public
 アウトラインのスタイルをカスタマイズします。
SetMatrix public
 Matrix プロパティを設定します。
TextHeight public
 現在の Font でレンダリングされるテキストの高さを、ピクセルで返します。
TextToPath public
 揃え位置、現在のフォントが指定されたテキスト文字列から、TPathData を作成します。
TextWidth public
 現在のフォント でレンダリングされるテキストの幅を、ピクセルで返します。
ToString public
 クラス名を表す文字列を返します。
UnitName public
 クラスが定義されているユニットの名前を返します。
UnitScope public クラスのユニット スコープを返します。
UnmapBitmap public
 
VCLの Pixelsプロパティそのもの、というのは無いと思いますが、マップ(Map)を使えば多少ややこしいものの同様の操作は出来るのではないかと思います。
 
また、回転系では、Direct2D同様、Matrixを使う事になると思われます。
 
 
なお、速度的には、VCLアプリケーションで
procedure TForm1.Button1Click(Sender: TObject);
var
 d : TDateTime ;
 i : integer ;
begin
 d := Now ;
 with PaintBox1 do begin
  for i:=1 to 100000 do begin
   Canvas.Pen.Color := dword(i) ;
   Canvas.MoveTo(0,i);
   Canvas.LineTo(100000,i) ;
  end;
 end;
 d := Now - d ;
 ShowMessage('時間:'+FormatDateTime('hh:nn:ss.zzz',d));
end;
というプログラムを作成して実行した結果は、この普通のノートパソコンの場合、340ミリ秒程度ですが、FireMonkeyアプリケーションで
procedure TForm1.Button1Click(Sender: TObject);
var
 d : TDateTime ;
 i : integer ;
begin
 d := Now ;
 with PaintBox1 do begin
  Canvas.BeginScene ;
  Canvas.Stroke.Kind := TBrushKind.bkSolid ;
  for i:=1 to 100000 do begin
   Canvas.Stroke.Color := $FF000000 + dword(i) ;
   Canvas.DrawLine(PointF(0,i),PointF(100000,i),1.0) ;
  end;
  Canvas.EndScene ;
 end;
 d := Now - d ;
 ShowMessage('時間:'+FormatDateTime('hh:nn:ss.zzz',d));
end;
というプログラムを開発環境(IDE)から実行した場合の結果は、790ミリ秒程度と、約2倍の時間が掛かっています。しかし、DelphiXE3 プログラム開発環境を終了し、エクスプローラ等から、出来上がった実行型ファイルをダブルクリックして動作させた場合の結果は、300ミリ秒程度となります。つまり、少なくともこの件のプログラムに関しては、VCLアプリケーション以下の時間で実行する事が出来ます。勿論これは、CPUやGPUによって動作速度は変化する可能性も高いので一概には言えないのですが、それよりは、MacOS等でのアプリ開発可能性という意味で有効であると思われますし、また、高速CPU・GPUを利用すれば、より高速動作が可能かもしれない?という意味において、既に頭打ち状態の WindowsGDI描画よりは、多少なりとも、期待は持てる?かもしれません。
 
 
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
>Delphi2010
>DelphiXE3
▲2013/12/26
 2013/12/27
▼2013/12/28
 
シェアウェア
Script!World
データベース
 
お問い合わせ 
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015. By AFsoft All Rights Reserved.