  
  
  
   
   
   
   
   
   
  | 
| 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 
データベース 
  |