Home New Help Edit

Delphi FireMonkey

Suns & Moon Laboratory
DelphiのFireMonkeyネタです。


スレッド

(iOSのバグで)メモリリークがあるため、対策必要。
http://www.s-m-l.org/dev/delphi.html#TAnonymousThread

サンプル

http://docwiki.embarcadero.com/RADStudio/XE6/ja/%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AE%E8%AA%AC%E6%98%8E

モバイルアプリの注意点

文字列のインデックスが0→TStringHelperを使う
System.Pos→TStringHelper.IndexOf
System.Copy→TStringHelper.Substring
System.Delete→TStringHelper.Remove
System.SysUtils.Trim→TStringHelper.Trim
TStringHelper.Chars[](読み取り専用)プロパティを利用すると、インデックス0からアクセス出来る
for i=1 to Length(s) do→for Low(s) to High(s) do
静的配列 array [10] of integer→動的配列 array of integer,TArray


デスクトップ アプリケーションからモバイル アプリケーションへの Delphi コードの移行

ジェスチャ

FireMonkey でのジェスチャ

ActionのUnsupportedPlatforms

XE5
チェックしておくと、チェックしたプラットフォームではコントロールが非表示になる。便利。

多重解像度ビットマップ

XE5
MultiResBitmap エディタ
多重解像度ビットマップの使用
12 多重解像度のアイコンおよび画像の使用


フォント

Android アプリケーションでのカスタム フォントの使用 iOS5,iOS6,Androidのフォント情報へのリンク

ログ

iOS simulatorは、OSXの場合Application->その他→コンソール.appを起動して、Library/Logs -> iOS Simulator -> system.log に表示される。
iOS実機は、Xcode -> Window -> Organizer -> DEVICES -> (実機を選択) -> Console
Androidは、Android SDK -> monitor

uses FMX.Platform; var log: IFMXLoggingService; begin log := TPlatformServices.Current.GetPlatformService(IFMXLoggingService) as IFMXLoggingService; log.Log('%s', [str]);

条件コンパイル

iOSとかANDROIDで条件コンパイル
{$IF DEFINED(iOS) or DEFINED(ANDROID)} {$ENDIF}
Windows(32,64問わず)で条件コンパイル
{$IFDEF MSWINDOWS} {$ENDIF}
XE6 docwiki 条件付きコンパイル(Delphi)

イベントいろいろ

iOSとWindows8のイベント対応
iOS 開発者のためのアプリのライフサイクル

iOSのイベント対応方法
Thread: How to trigger OnClose, OnCloseQuery or OnDestroy events on iOS?

FMX.Platform.TApplicationEvent


で、iPadで試してみる
iPadのスリープボタンを押して、スリープすると
aeEnteredBackground
スリープ解除すると
aeWillBecomeForeground
aeBecameActiveが来る。

ちなみに、FormのOnActiveは起動時来るけどスリープの時とかは来ないので、この方法で取得しないとダメっぽい。

ListBoxでいろいろ表示

XE4
http://worktoolsmith.com/2013/05/delphi-xe4-listview/

XE5 モバイルアプリだと、スタイルいじれない?

モバイル チュートリアル:リスト ボックス コンポーネントを使用してテーブル ビューを表示する(iOS および Android)

TListViewで検索

Textに対して検索
Delphi XE5の新機能「TListViewのビルトイン検索フィルタリング」を試してみた

TListBoxのTSearchBoxみたいにするには、EditboxのOnChangeTrackingで検索をかける。

TListBoxで検索

TextとDetailを検索
TListBoxはListBoxを右クリックして、項目の追加から「TSearchBox」を追加すると検索機能が追加される。コード不要。

メモを自動でスクロール

VCL版TMemoと違って、Lines.Addした時に自動スクロールしないので、コード追加して対処。
ログを垂れ流すとかなら、これで良いかなと。
Memo1.Lines.Add(str); Memo1.ScrollTo(0, Memo1.Font.Size * 2 * Memo1.Lines.Count);
ちなみに、細かくスクロールする方法はこれ。
Memo1.ScrollTo(0, -1);
これだとなんかダメだった。場合によって変な位置になる。
Memo1.Lines.Add(str); Memo1.GoToTextEnd; Memo1.GoToLineBegin;
Delphi10.1Seatle
現状これでうまくいってる。
Memo1.Lines.Add(str); Memo1.GoToTextEnd;

VidoeCapture

DelphiXE3_FireMonkey_VideoCapture

サンプルフォルダ

C:\Users\Public\Documents\RAD Studio\10.0\Samples\FireMonkey

画像描画


基本

TPaintBoxのOnPaintで、BeginScene〜EndSceneの間に描画処理を書く。
(Delphi10.1で、TImage使うとなんかFormのCanvasに描画されているっぽい)

Formへの直接描画

XPはだめ。Direct2Dがデスクトップでサポートされていないかららしい。ええぇぇ。

描画タイミング

OnPaintにて、BeginScene〜EndSceneの間に描画処理を書く。

XPがダメなのとは話違うのだが、たとえばButtonクリックイベントで描画しようとするのは書けない。
OnPaintに書くのが良い。

XE7upd1+Win7 Form1.Canvasで書ける。
XE7upd1+Nexus7(5.0.2) Form1.Canvasでは書けない。OnPaintのCanvasなら書ける。
XE7upd1+iPad(8.1.3) Form1.Canvasでは書けない。OnPaintのCanvasなら書ける。

OnPaintで書けばOKという事で。

TAlphaColor を使う(VCLはTColor)

色定数

clXXじゃなくてclaXX。
uses System.UIConsts claRed claGreen claBlue claBlack claWhite
http://docwiki.embarcadero.com/RADStudio/XE3/ja/VCL_%E3%81%8B%E3%82%89_FireMonkey_%E3%81%B8%E3%81%AE%E5%A4%89%E6%8F%9B
http://delphimaniacs.blogspot.jp/2012/10/vcl-fmx-color-2.html

DrawLine

10.1
procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); begin Canvas.BeginScene; Canvas.Stroke.Kind:=TBrushKind.Solid; Canvas.Stroke.Color := claBlack; Canvas.StrokeThickness := 1.0; Canvas.DrawLine(PointF(0, 0), PointF(100, 100), 1.0); Canvas.EndScene; end;
古い
ImageControl1.Bitmap.Create(Trunc(ImageControl1.Width), Trunc(ImageControl1.Height)); ImageControl1.Bitmap.Canvas.BeginScene; try ImageControl1.Bitmap.Clear($FFFFFFFF); ImageControl1.Bitmap.Canvas.Stroke.Color := $FF000000; ImageControl1.Bitmap.Canvas.DrawLine(PointF(10, 10), PointF(100, 100), 100); ImageControl1.Bitmap.Canvas.Stroke.Color := $FF0000FF; ImageControl1.Bitmap.Canvas.DrawLine(PointF(10, 10), PointF(100, 120), 100); ImageControl1.Bitmap.Canvas.Stroke.Color := $FF00FF00; ImageControl1.Bitmap.Canvas.DrawLine(PointF(10, 10), PointF(100, 130), 100); ImageControl1.Bitmap.Canvas.Stroke.Color := $FFFF0000; ImageControl1.Bitmap.Canvas.DrawLine(PointF(10, 10), PointF(100, 140), 100); finally ImageControl1.Bitmap.Canvas.EndScene; end;
http://www.freeml.com/delphi-users/2185


FillRect

全部塗りつぶすならClearが良い。
bmp.Canvas.BeginScene; try bmp.Canvas.Fill.Color := claBlack; bmp.Canvas.Fill.Kind := TBrushKind.Solid; bmp.Canvas.FillRect(ARect, 0, 0, AllCorners, 1.0); finally bmp.Canvas.EndScene; end;

Clear

全部塗りつぶし
bmp.Clear(claBlack);

GetPixel,SetPixel

Delphi10.1
BitmapにGetPixel,SetPixel無いが、BitmapDataにはある。

procedure TForm1.Button1Click(Sender: TObject); var bmp: TBitmap; bmp_data: TBitmapData; begin bmp := Image1.Bitmap; if bmp.Map(TMapAccess.maReadWrite, bmp_data) then begin ColorBox1.Color := bmp_data.GetPixel(Round(Image1.Width / 2), Round(Image1.Height / 2)); bmp.Unmap(bmp_data); end; end;
http://www.synaptica.info/it/2016/04/11/firemonkey-bitmap-scaling-without-aliasing-android/

BitmapChanged無い

XE4
TBitmap.BitmapChangedがPrivateメソッドになっているので、BitmapChanged呼び出せない。
ソース読むと、Canvas.EndSceneで呼び出している。

Styleの摘要

FireMonkey アプリケーションでの Retina スタイルと非 Retina スタイル

Styleを外部ファイルから読み込み

usesにFMX.Styles追加して、下記実行
TStyleManager.SetStyleFromFile(fname);
適用するスタイルによっては、コンポーネントのサイズが変わったり変わらなかったりするので注意。
Touch系のスタイルはコンポーネントサイズが大きい。
アプリ起動→適用は1回のみが安全ぽい。(適用するスタイルによる)

(Delphi10.1)

時間を計る

GetTick

http://ht-deko.minim.ne.jp/techf021.html

FM3でPlatform変数は廃止されたようで、こう書かないと動かない...
var tick: Double; TimerService: IFMXTimerService; begin TimerService := IFMXTimerService(TPlatformServices.Current.GetPlatformService(IFMXTimerService)); tick := TimerService.GetTick; Sleep(500); Memo(FloatToStr(TimerService.GetTick - tick)); end;

Stopwatch

var sw: TStopwatch; tick: integer; begin sw := TStopwatch.StartNew; tick := sw.ElapsedMilliseconds; Sleep(500); Memo(IntToStr(sw.ElapsedMilliseconds - tick)); end;

ファイル操作

ディスクおよびディレクトリ サポート ルーチン
クロスプラットフォームの為に、IOUtilsかSysUtilsを使う。

ファイルコピー
System.IOUtils.pas
Copy

ディレクトリ作成(親も作成)
System.SysUtils.pas
ForceDirectories

ディレクトリ存在判断
System.SysUtils.pas
DirectoryExists

ファイルパス取得


サポートされているターゲット プラットフォームに適した標準の RTL パス関数

マルチユーザ対応 Android 4.2以降の内部ストレージと外部ストレージ (4.4対応を追記)

Win7+GalaxyNexus(Android4.2.2)の組み合わせで、PCを再起動しないと内部ストレージが見えない時がある。不便。

XE6 + Galaxy Nexus(Android 4.2.2)の例
Memo1.Lines.Add(TPath.GetHomePath); // '/data/data/com.embarcadero.test_app/files Memo1.Lines.Add(TPath.GetDocumentsPath); // 同上 Memo1.Lines.Add(TPath.GetSharedDocumentsPath); // '/storage/emulated/0/Android/data/com.embarcadero.test_app/files Memo1.Lines.Add(TPath.GetPublicPath); // 同上 Memo1.Lines.Add(TPath.GetTempPath); // '/storage/emulated/0/Android/data/com.embarcadero.test_app/files/tmp
上記をPC(Windows7)から内部ストレージとして見ると、こう見える
コンピューター\Galaxy Nexus\内部ストレージ\Android\data\com.embarcadero.test_app\files
Windows7の例
uses System.IOUtils; GetHomePath TPath.GetTempPath TPath.GetDocumentsPath TPath.GetLibraryPath TPath.GetTempFileName TPath.GetTempFileName ParamStr(0) //従来のApplication.Exenameの代わりに使う C:\Users\ユーザー名\AppData\Roaming C:\Users\ユーザー名\AppData\Local\Temp\ C:\Users\ユーザー名\Documents C:\app_path\Win32\Debug\ C:\Users\ユーザー名\AppData\Local\Temp\tmpA031.tmp C:\Users\ユーザー名\AppData\Local\Temp\tmpA032.tmp C:\app_path\Win32\Debug\test_path.exe
iOS,Androidはこんな感じ。
配置でとかする。
Androidはリモートパスを「.\assets\internal\」にして配置。
iOSはリモートパスを「StartUp\Documents」にして配置。
uses System.IOUtils; TPath.Combine(TPath.GetDocumentsPath, 'dbdemos.gdb');
Android アプリケーションの作成 ファイルの読み込みと配置

実際の配置先は、これの下の方
How to Develop Android Database Applications in RAD Studio XE5

エクスプローラからドラッグドロップ


FMXコンポーネントのTDropTarget

TDropTargetをフォーム上に配置
Fileterに任意のフィルターを設定
*.txt
OnDragDropイベント記述
procedure TForm1.DropTarget1DragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF); begin memo(Data.Files[0]); end;
Delphi10.1

WindowHandle(Windows)

どうしてもWindowsのAPI呼びたい時

uses FMX.Platform.Win, Winapi.Windows; procedure TForm1.Button1Click(Sender: TObject); begin Form2.Show; end; procedure TForm1.Button2Click(Sender: TObject); var hw: HWND; begin hw := FmxHandleToHWND(Form2.Handle); end;

LoadFromFile

XE5
stringsで使えるLoadFromFile。
iOSとAndroidはSJISだと読めないっぽい。UNICODEにして読み込めた。

パス(画像、アニメーション)

InkScapeで作って、SVGからパスデータをコピー、RAD Studioのパスデザイナにペースト。

証明書

XE5
認証したmacと、別のmacで開発しようとすると、XcodeのOrganizerで、こんなエラーが出る。
Organizer -> Provisioning Profiles -> Status
Valid signing identity not found
証明書を持ってこないとダメらしい。
2台目のMacのXcode:「Valid signing identity not found」

証明書が複数ある場合

"iPhone Developer: ambiguous"とか出た場合は、複数の証明書があって名前解決出来なかった時
指定された証明書名があいまい
ツール→オプション→環境オプション→プロビジョニング→デベロッパ証明書を、キーチェーンの名前にする。(十分一致する長さがあればいい)

iOS Developer

アクティベーションに失敗した時の話
日本のApple StoreでiOS Developer Programを購入しActivateするまでの全スクリーンショット

MacとWin

Delphiを使ってMacOSX用アプリを作る

フォーム(デバイス)の向き(XE5)

プロジェクト→オプション→アプリケーション→向き→カスタムの向き で指定する

デベロッパーキャンプ・アーカイブ

デベロッパーキャンプ・アーカイブ
Delphi for iOS開発ファーストステップ 必読
Windows開発者のためのFireMonkeyモバイル開発入門 必読,iOS or ANDROID?,画面サイズと画面密度
モバイル開発始めるなら今でしょ!Delphi iOSアプリ開発講座 iOS配置マネージャ
FireMonkeyファーストインプレッション パスの作成方法。VCLコンポーネントとの相違点とか、3Dとか色々書いてあるので一読お勧め
基礎から学ぶビジュアルAndroidアプリ開発今日からあなたもAndroidデベロッパー 基礎から丁寧に解説。必読

classes.dexの配置

10.1update2
昔作ったソフトが動かなかった
エラーは下記
com/embarcadero/rtl/ProxyInterface が見つかりません。
で、ここらへんとか経由して
XE10 - Java class com/embarcadero/rtl/ProxyInterface could not be found
ここ
Delphi XE8 and Seattle: Android App didn't start
からのここ
手動での classes.dex ファイルの作成と配置

最終的にプロジェクト→配置でclasses.dexをプロジェクト下にある物を配置するように変更。


チュートリアル

モバイル チュートリアル:Delphi モバイル アプリケーション開発(iOS および Android)
モバイル チュートリアル:リスト ボックス コンポーネントを使用してテーブル ビューを表示する(iOS および Android)

Androidログビューア

シリアルゲームズ製
android log viewer

リンク

Delphi XE3 FireMonkey変更点
delphi maniacs FireMonkey
全力わはー TMessageManagerってこんなの。
Delphi (FireMonkey) によるテクニック&アルゴリズム
想いが星空を巡る頃 Delphi XE2、FireMonkeyのCanvas描画サンプル

FireMonkey: 設計時、スタイルにアニメーション効果を適用する
FireMonkey - Androidアプリの[Back]キーとライフサイクル
FireMonkey Premium Style Pack 3 for RAD Studio XE5 が公開されました

Delphi モバイル コンパイラでの自動参照カウント うーむ、どうなんだろ

http://ht-deko.minim.ne.jp/Delphi/index.html dekoさんがまとめている情報。便利〜

全力わはー TMessageManagerってこんなの。

Home New Help Edit
2017-02-06 10:44:17 32400