firemonkey
*Delphi FireMonkey memo [[index]] DelphiのFireMonkeyネタです。 [[dev/delphi]] FireMonkey以外のネタはこっち #contents **印刷 [[FireMonkey アプリケーションからの印刷>http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/FireMonkey_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8B%E3%82%89%E3%81%AE%E5%8D%B0%E5%88%B7]] 1.FMX.Printerの追加 >uses FMX.Printer; 2.BeginScene,EndScene使用fmac ちょっと意味わかんない 3.DPI選択 >Printer.ActivePrinter.SelectDPI(600,600); あくまで選択なので、一致するDPIが無い場合は、プリンターが持つDPIが設定される。 例えば300DPI,600DPIをプリンタがサポートしている場合 SelectDPI(350,350) -> 300DPIが選択される SelectDPI(550,550) -> 600DPIが選択される ※プリンタドライバによって、何が選択されるかは挙動違う事がありそう。 なので、SelectDPIで選択したら、選択されたDPIを利用して描画する必要が有る。 >Printer.ActivePrinter.DPI[Printer.ActivePrinter.ActiveDPIIndex].X >Printer.ActivePrinter.DPI[Printer.ActivePrinter.ActiveDPIIndex].Y 手持ちのプリンタBrother MFC-J827DNの場合、SelectDPI設定してもActiveDPIIndex=-1のままで変わらない。 従ってDPIの読み出しも不可。 ...DPI無視して描画するしかないのか。 4.印刷ジョブ開始 >Printer.BeginDoc; 5.印刷ジョブ終了 >Printer.EndDoc; **スレッド (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 コードの移行>http://docwiki.embarcadero.com/RADStudio/XE6/ja/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8B%E3%82%89%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%B8%E3%81%AE_Delphi_%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E7%A7%BB%E8%A1%8C]] **ジェスチャ [[FireMonkey でのジェスチャ>http://docwiki.embarcadero.com/RADStudio/XE5/ja/FireMonkey_%E3%81%A7%E3%81%AE%E3%82%B8%E3%82%A7%E3%82%B9%E3%83%81%E3%83%A3]] **ActionのUnsupportedPlatforms XE5 チェックしておくと、チェックしたプラットフォームではコントロールが非表示になる。便利。 **多重解像度ビットマップ XE5 [[MultiResBitmap エディタ>http://docwiki.embarcadero.com/RADStudio/XE5/ja/MultiResBitmap_%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF]] [[多重解像度ビットマップの使用>http://docwiki.embarcadero.com/RADStudio/XE5/ja/%E5%A4%9A%E9%87%8D%E8%A7%A3%E5%83%8F%E5%BA%A6%E3%83%93%E3%83%83%E3%83%88%E3%83%9E%E3%83%83%E3%83%97%E3%81%AE%E4%BD%BF%E7%94%A8]] [[12 多重解像度のアイコンおよび画像の使用>http://docwiki.embarcadero.com/RADStudio/XE5/ja/Android_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90#.E5.A4.9A.E9.87.8D.E8.A7.A3.E5.83.8F.E5.BA.A6.E3.81.AE.E3.82.A2.E3.82.A4.E3.82.B3.E3.83.B3.E3.81.8A.E3.82.88.E3.81.B3.E7.94.BB.E5.83.8F.E3.81.AE.E4.BD.BF.E7.94.A8]] **いろいろ >uses System.Types; >RectF() **フォント [[Android アプリケーションでのカスタム フォントの使用>http://docwiki.embarcadero.com/RADStudio/XE5/ja/Android_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90#Android_.E3.82.A2.E3.83.97.E3.83.AA.E3.82.B1.E3.83.BC.E3.82.B7.E3.83.A7.E3.83.B3.E3.81.A7.E3.81.AE.E3.82.AB.E3.82.B9.E3.82.BF.E3.83.A0_.E3.83.95.E3.82.A9.E3.83.B3.E3.83.88.E3.81.AE.E4.BD.BF.E7.94.A8]] 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)>http://docwiki.embarcadero.com/RADStudio/XE6/ja/%E6%9D%A1%E4%BB%B6%E4%BB%98%E3%81%8D%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%EF%BC%88Delphi%EF%BC%89]] **イベントいろいろ iOSとWindows8のイベント対応 [[iOS 開発者のためのアプリのライフサイクル>http://msdn.microsoft.com/ja-jp/library/windows/apps/dn263207.aspx]] iOSのイベント対応方法 [[Thread: How to trigger OnClose, OnCloseQuery or OnDestroy events on iOS? >https://forums.embarcadero.com/message.jspa?messageID=558241]] [[FMX.Platform.TApplicationEvent>http://docwiki.embarcadero.com/Libraries/XE5/ja/FMX.Platform.TApplicationEvent]] で、iPadで試してみる iPadのスリープボタンを押して、スリープすると aeEnteredBackground スリープ解除すると aeWillBecomeForeground aeBecameActiveが来る。 ちなみに、FormのOnActiveは起動時来るけどスリープの時とかは来ないので、この方法で取得しないとダメっぽい。 **ListBoxでいろいろ表示 XE4 [[http://worktoolsmith.com/2013/05/delphi-xe4-listview/]] XE5 モバイルアプリだと、スタイルいじれない? [[モバイル チュートリアル:リスト ボックス コンポーネントを使用してテーブル ビューを表示する(iOS および Android)>http://docwiki.embarcadero.com/RADStudio/XE5/ja/%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%EF%BC%9A%E3%83%AA%E3%82%B9%E3%83%88_%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9_%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB_%E3%83%93%E3%83%A5%E3%83%BC%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%EF%BC%88iOS_%E3%81%8A%E3%82%88%E3%81%B3_Android%EF%BC%89]] **TListViewで検索 Textに対して検索 [[Delphi XE5の新機能「TListViewのビルトイン検索フィルタリング」を試してみた>http://www.gesource.jp/weblog/?p=6265]] TListBoxのTSearchBoxみたいにするには、EditboxのOnChangeTrackingで検索をかける。 **TListBoxで検索 TextとDetailを検索 TListBoxはListBoxを右クリックして、項目の追加から「TSearchBox」を追加すると検索機能が追加される。コード不要。 **TComboBox ***アイテムが多い時,ドロップダウンしたリストが、現在選択している項目を表示しない。 (10.2Tokyo) DropDownKindをCustomに変更する。 **TScrollBar ***Max変更しても変わらない (10.2Tokyo) Max > ViewPortSize > new_max ※ここの条件詳細に確認してないけど大体こんな感じ の時 Max := new_max とやると、Maxが変わらない。 Max代入前にViewPortSize:=0にしておくとMaxが変更 ***ViewPortSize (10.2Tokyo) [[http://docwiki.embarcadero.com/Libraries/Tokyo/ja/FMX.StdCtrls.TScrollBar.ViewportSize]] ヘルプ見てもよくわからないのですが、実際はこう。 Min,Max : スクロールバーのスクロール範囲 ViewPortSize : スクロールバーのトラックバー(掴んでスクロール出来るバー)の範囲 例えば Min=0,Max=100で、ViewPortSize=50とすれば、スクロールバーの半分のサイズのトラックバーが表示される。 ViewPortSize=20とすれば、1/5サイズのトラックバーが表示される。 ***トラックバー以外をクリックした時の動作 (10.2Tokyo) トラックバー以外をクリックした時のスクロール量が少なすぎるのだが、どうにもならない... **メモを自動でスクロール VCL版TMemoと違って、Lines.Addした時に自動スクロールしないので、コード追加して対処。 ログを垂れ流すとかなら、これで良いかなと。 Delphi11.3でOK > 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.1 OK Delphi11.3 NG EArgumentOutOfRangeExceptionでそのうち死ぬ > Memo1.Lines.Add(str); > Memo1.GoToTextEnd; **VideoCapture [[xe3_fm2_videocapture]] **サンプルフォルダ >C:\Users\Public\Documents\RAD Studio\10.0\Samples\FireMonkey **画像描画 ***基本 TPaintBoxのOnPaintで、BeginScene〜EndSceneの間に描画処理を書く。 (Delphi10.1で、TImage使うとなんかFormのCanvasに描画されているっぽい) ★BeginScene〜EndSceneの数が合わないと、変な事が起きます... ***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]] ***クリッピング [[Clipping Rectangles in FireMonkey>http://blog.analogmachine.org/2012/09/30/clipping-rectangles-in-firemonkey/]] Canvas.IntersectClipRectを使用する SaveState,RestoreState使わないと他の描画に影響でるので、使った方が良い >procedure TIxBG.Draw(Canvas: TCanvas); >var > src_rct: TRectF; > dst_rct: TRectF; > clip_rct: TRectF; > wd2, hd2: Single; > w, h: Single; > save: TCanvasSaveState; >begin > if Bitmap = nil then > Exit; > > wd2 := (Bitmap.Width / 2) * DrawParams.Scale * Scale; > hd2 := (Bitmap.Height / 2) * DrawParams.Scale * Scale; > w := (DrawParams.Width / 2) * DrawParams.Scale * Scale; > h := (DrawParams.Height / 2) * DrawParams.Scale * Scale; > src_rct := RectF(0, 0, Bitmap.Width - 1, Bitmap.Height - 1); > dst_rct := RectF(X - wd2, Y - hd2, X + wd2 - 1, Y + hd2 - 1); > clip_rct := RectF(X - w, Y - h, X + w - 1, Y + h - 1); > > save := Canvas.SaveState; > try > Canvas.IntersectClipRect(clip_rct); > Canvas.DrawBitmap(Bitmap, src_rct, dst_rct, 1.0); > finally > Canvas.RestoreState(save); > end; >end; ***OnPaintint,Invalidate,InvalidateRectFで描画範囲を限定する OnPaintじゃなくてOnPaintingを使うと、描画矩形を取得できる。 ★とおもったが、取得できてないのでダメ ★だめだけど残しておく >var > rct, rct1, rct2, rct3: TRectF; > count: integer; > >procedure TForm1.FormCreate(Sender: TObject); >begin > rct1 := RectF(0, 0, 100, 99); > rct2 := RectF(0, 100, 100, 199); > rct3 := RectF(0, 200, 100, 299); >end; > >procedure TForm1.Button1Click(Sender: TObject); >begin > PaintBox1.InvalidateRect(rct1); >end; > >procedure TForm1.Button2Click(Sender: TObject); >begin > PaintBox1.InvalidateRect(rct2); >end; > >procedure TForm1.Button3Click(Sender: TObject); >begin > PaintBox1.InvalidateRect(rct3); >end; > >procedure TForm1.Button4Click(Sender: TObject); >begin > Invalidate; >end; > >procedure TForm1.PaintBox1Painting(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); >begin > Canvas.BeginScene; > if IntersectRectF(rct, ARect, rct1) then > begin > Canvas.Fill.Color := claRed; // 塗りつぶし色 > Canvas.FillRect(rct1, 1.0); > Canvas.Fill.Color := claWhite; // 文字色 > Canvas.FillText(rct1, count.ToString, true, 1.0, [], TTextAlign.Center, TTextAlign.Center); > inc(count); > end; > > if IntersectRectF(rct, ARect, rct2) then > begin > Canvas.Fill.Color := claGreen; // 塗りつぶし色 > Canvas.FillRect(rct2, 1.0); > Canvas.Fill.Color := claWhite; // 文字色 > Canvas.FillText(rct2, count.ToString, true, 1.0, [], TTextAlign.Center, TTextAlign.Center); > inc(count); > end; > > if IntersectRectF(rct, ARect, rct3) then > begin > Canvas.Fill.Color := claBlue; // 塗りつぶし色 > Canvas.FillRect(rct3, 1.0); > Canvas.Fill.Color := claWhite; // 文字色 > Canvas.FillText(rct3, count.ToString, true, 1.0, [], TTextAlign.Center, TTextAlign.Center); > inc(count); > end; > Canvas.EndScene; >end; ***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.Stroke.Thickness := 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; ***FillText 10.2Tokyo 例では背景をFillRectで塗りつぶしている > Canvas.Fill.Kind := TBrushKind.Solid; > Canvas.Fill.Color := fill_color; > Canvas.FillRect(rct, 0, 0, AllCorners, 1.0); > Canvas.Fill.Color := font_color; > Canvas.FillText(rct, text, true, 1.0, [], TTextAlign.Center, TTextAlign.Center); ちなみに[]のところ[TFillTextFlag.RightToLeft]にすると、単語が右から左に配置される... ***DrawRect XE10.1 枠を描画する。 >Canvas.Stroke.Kind := TBrushKind.Solid; //※これ指定しないと描画されない時あるので注意。 ***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で呼び出している。 ***Canvas.Scaleの変更 Canvas.Scaleは読み込みようなので変更出来ない...のだが、SetMatrixでの変更は可能 [[https://stackoverflow.com/questions/23609523/firemonkey-xe6how-to-use-the-full-resolution-on-my-adroiddevice]] >bg_bitmap.Canvas.SetMatrix(TMatrix.CreateScaling(XScale, YScale)); ***SetMatrixを使うには TMatrixを使って、Matrixを生成する [[http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Math.Vectors.TMatrix]] ***TPathDataでテキストの描画 一旦TextToPathでTPathDataに変換してからTPathDataを描画する。 >procedure TForm1.draw_text(txt: string); >var > pd: TPathData; > txt_width: Single; > draw_width: Single; >begin > txt := Edit1.Text; > pd := TPathData.Create; > try > // 背景塗りつぶし > bmp.Canvas.BeginScene; > bmp.Canvas.Fill.Color := claBlack; > bmp.Canvas.FillRect(RectF(0, 0, bmp.Width, bmp.Height), 1.0); > > // フォント外形線 > bmp.Canvas.Font.Size := bmp.Height; > bmp.Canvas.TextToPath(pd, Rect(0, 0, bmp.Width, bmp.Height), txt, false, TTextAlign.Leading); > bmp.Canvas.Stroke.Kind := TBrushKind.Solid; > bmp.Canvas.Stroke.Color := $FFFF8000;; > > // フォント塗りつぶし > bmp.Canvas.Fill.Color := $FFFF8000; > > // 横幅変更 > txt_width := bmp.Canvas.TextWidth(txt); > if txt_width > bmp.Width then > draw_width := bmp.Width / txt_width > else > draw_width := 1.0; > > // 描画 > pd.Scale(draw_width, 1.0); > bmp.Canvas.FillPath(pd, 1.0); > bmp.Canvas.DrawPath(pd, 1.0); > bmp.Canvas.EndScene; > > ImageViewer1.Bitmap := bmp; > finally > pd.Free; > end; >end; ***DrawPathで矩形描画 Delphi11 >procedure TForm1.PaintBox1Painting(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); >var > pd: TPathData; >begin > Canvas.BeginScene; > try > Canvas.Stroke.Kind := TBrushKind.Solid; > Canvas.Stroke.Color := claBlack; > Canvas.Stroke.Thickness := 1.0; > pd := TPathData.Create; > pd.MoveTo(PointF(10, 10)); > pd.LineTo(PointF(100, 100)); > pd.LineTo(PointF(110, 100)); > pd.LineTo(PointF(120, 120)); > pd.LineTo(PointF(130, 120)); > Canvas.DrawPath(pd, 1.0); > pd.Free; > finally > Canvas.EndScene; > end; >end; **マルチディスプレイ Delphi 11.3 > procedure TForm1.PaintBox1Painting(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); > begin > Canvas.BeginScene; > try > Canvas.Stroke.Kind := TBrushKind.Solid; > Canvas.Stroke.Color := claBlack; > Canvas.Stroke.Thickness := 1.0; > Canvas.DrawLine(PointF(0, 0), PointF(100, 100), 1.0); > finally > Canvas.EndScene; > end; > end; > > // マルチディスプレイの情報を表示 > procedure TForm1.Button1Click(Sender: TObject); > begin > Screen.UpdateDisplayInformation; > UpdateMemo; > end; > > // ウィンドウを指定位置へ移動 > procedure TForm1.Button2Click(Sender: TObject); > begin > Left := 3840; > Top := 1520; > end; > > // ウィンドウを指定したサイズのディスプレイへ移動 > procedure TForm1.Button3Click(Sender: TObject); > begin > Screen.UpdateDisplayInformation; > move_win(1024, 600); > end; > > // w,hが一致するDisplayへウィンドウを移動する > procedure TForm1.move_win(w, h: integer); > begin > for var I := 0 to Screen.DisplayCount - 1 do > begin > if (Screen.Displays[I].BoundsRect.Width = w) and (Screen.Displays[I].BoundsRect.Height = h) then > begin > Left := Round(Screen.Displays[I].BoundsRect.Left); > Top := Round(Screen.Displays[I].BoundsRect.Top); > break; > end; > end; > end; > > function TForm1.RectfToStr(R: TRectF): String; > begin > Result := '(Left,Top=' + Floattostr(R.Left) + ',' + Floattostr(R.Top) + ' W,H=' + Floattostr(R.Width) + ',' + Floattostr(R.Height) + ')'; > end; > > function TForm1.DispToStr(Disp: TDisplay): String; > begin > Result := Inttostr(Disp.Index) + '. '; > > if Disp.Primary then > Result := Result + ' Primary '; > > Result := Result + SLineBreak; > Result := Result + 'WorkAreaRect : ' + RectfToStr(Disp.WorkareaRect) + '; '; // タスクバーの領域除外 > > Result := Result + SLineBreak; > Result := Result + 'BoundsRect : ' + RectfToStr(Disp.BoundsRect) + '; '; // タスクバー含めた画面サイズ > end; > > procedure TForm1.UpdateMemo; > var > I: integer; > P: TPoint; > begin > Memo1.Lines.Clear; > P := TPoint.Create(Round(Screen.MousePos.X), Round(Screen.MousePos.Y)); > Memo1.Lines.Add('Screen'); > Memo1.Lines.Add('MousePos: ' + Floattostr(P.X) + ' ' + Floattostr(P.Y)); > Memo1.Lines.Add('DisplayFromForm(Self).Index: ' + Inttostr(Screen.DisplayFromForm(Self).Index)); > Memo1.Lines.Add('Size.cx: ' + Floattostr(Screen.Size.cx)); > Memo1.Lines.Add('Size.cy: ' + Floattostr(Screen.Size.cy)); > Memo1.Lines.Add('DisplayCount: ' + Inttostr(Screen.DisplayCount)); > Memo1.Lines.Add('WorkAreaRect: ' + RectfToStr(Screen.WorkareaRect)); > Memo1.Lines.Add('DesktopRect: ' + RectfToStr(Screen.DesktopRect)); > Memo1.Lines.Add('Displays'); > for I := 0 to Screen.DisplayCount - 1 do > Memo1.Lines.Add(DispToStr(Screen.Displays[I])); > Memo1.Lines.Add('Form'); > Memo1.Lines.Add('BoundsRect: ' + RectfToStr(TRect.Create(TPoint.Create(Left, Top), Width, Height))); > end; **Styleの摘要 ***Styleを適用する StyleBooxをFormにドロップ StyleBook1ダブルクリック スタイルデザイナ→開くアイコンクリック スタイルを開く スタイルデザイナ閉じる Form->リンク→StyleBookにStyleBook1を指定 ***Retinaスタイル [[FireMonkey アプリケーションでの Retina スタイルと非 Retina スタイル>http://docwiki.embarcadero.com/RADStudio/XE3/ja/FireMonkey_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A7%E3%81%AE_Retina_%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%A8%E9%9D%9E_Retina_%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB]] ***Styleを外部ファイルから読み込み usesにFMX.Styles追加して、下記実行 >TStyleManager.SetStyleFromFile(fname); 適用するスタイルによっては、コンポーネントのサイズが変わったり変わらなかったりするので注意。 Touch系のスタイルはコンポーネントサイズが大きい。 アプリ起動→適用は1回のみが安全ぽい。(適用するスタイルによる) (Delphi10.1) **ダイアログ MessageDlgの代替 uses FMX.DialogService.Sync; //FMXではこれ使う //注意:10.2で実行した所、ダイアログでエンター押すと、メインフォームにもキーイベントが発生します。 if TDialogServiceSync.MessageDialog('ファイルの先頭から検索を始めますか', TmsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], TMsgDlgBtn.mbYes, 0) = mrYes then begin // end; //こっちはFMX非推奨 if MessageDlg('ファイルの先頭から検索を始めますか?', TmsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0) = mrYes then begin // end; (Delphi10.1) ***ダイアログのフィルター FMXと違ってIDEで設定できない? [[FMX.Dialogs.TOpenDialog.Filter>https://docwiki.embarcadero.com/Libraries/Sydney/ja/FMX.Dialogs.TOpenDialog.Filter]] Delph11.3 > OpenDialog1.Filter:='WAV file (*.wav)|*.wav'; ***ディレクトリ選択ダイアログ VCLと違ってコンポーネントは無いけど関数で有る。 uses FMX.Dialogs SelectDirectory(Caption,Root,var Directory) (Delphi10.2) **時間を計る ***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 > uses System.Diagnostics; >var > sw: TStopwatch; > tick: integer; >begin > sw := TStopwatch.StartNew; > tick := sw.ElapsedMilliseconds; > Sleep(500); > Memo(IntToStr(sw.ElapsedMilliseconds - tick)); >end; **ファイル操作 [[ディスクおよびディレクトリ サポート ルーチン>http://docwiki.embarcadero.com/RADStudio/XE3/ja/%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%81%8A%E3%82%88%E3%81%B3%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA_%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88_%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3]] クロスプラットフォームの為に、IOUtilsかSysUtilsを使う。 ファイルコピー System.IOUtils.pas Copy ディレクトリ作成(親も作成) System.SysUtils.pas ForceDirectories ディレクトリ存在判断 System.SysUtils.pas DirectoryExists **ファイルパス取得 こっちにも [[http://www.s-m-l.org/dev/delphi.html#パス取得]] [[サポートされているターゲット プラットフォームに適した標準の RTL パス関数>http://docwiki.embarcadero.com/RADStudio/XE6/ja/%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88_%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AB%E9%81%A9%E3%81%97%E3%81%9F%E6%A8%99%E6%BA%96%E3%81%AE_RTL_%E3%83%91%E3%82%B9%E9%96%A2%E6%95%B0]] [[マルチユーザ対応 Android 4.2以降の内部ストレージと外部ストレージ (4.4対応を追記)>http://techbooster.org/android/application/16004/]] 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 アプリケーションの作成 ファイルの読み込みと配置>http://docwiki.embarcadero.com/RADStudio/XE5/ja/Android_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90#.E3.83.95.E3.82.A1.E3.82.A4.E3.83.AB.E3.81.AE.E8.AA.AD.E3.81.BF.E8.BE.BC.E3.81.BF.E3.81.A8.E9.85.8D.E7.BD.AE]] 実際の配置先は、これの下の方 [[How to Develop Android Database Applications in RAD Studio XE5>http://blog.devart.com/android-database-application-development-in-rad-studio-xe5.html]] **エクスプローラからドラッグドロップ ***FMXコンポーネントのTDropTarget Delphi10.1,Delphi11.3 TDropTargetをフォーム上に配置 Fileterに任意のフィルターを設定 >*.txt OnDragDropイベント記述 >procedure TForm1.DropTarget1DragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF); >begin > Memo1.Lines.Add(Data.Files[0]); > > //for var str in Data.Files do > // Memo1.Lines.Add(str) >end; **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にして読み込めた。 **クリップボード コピーペーストのやり方 10.2Tokyo IFMXExtendedClipboardService を使う [[http://docwiki.embarcadero.com/Libraries/Tokyo/ja/FMX.Clipboard.IFMXExtendedClipboardService]] サンプル [[https://sourceforge.net/p/radstudiodemos/code/HEAD/tree/branches/RADStudio_Tokyo/Object%20Pascal/Multi-Device%20Samples/User%20Interface/CopyPaste/fmMain.pas]] **パス(画像、アニメーション) InkScapeで作って、SVGからパスデータをコピー、RAD Studioのパスデザイナにペースト。 **TStringGrid ***表の使い方(基礎) Delphi11.3 > procedure TForm1.Grid1_Init; > begin > // 行数指定 > StringGrid1.RowCount := ROW_COUNT; > > //桁追加 > for var i := 0 to COL_COUNT - 1 do > begin > StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); > end; > > //桁の幅指定 > for var i := 0 to COL_COUNT - 1 do > begin > StringGrid1.Columns[i].Width := Floor(StringGrid1.Width / StringGrid1.ColumnCount); > end; > end; ***表の自前描画 Delphi11.3 > procedure TForm1.StringGrid1DrawColumnCell(Sender: TObject; const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF; > const Row: Integer; const Value: TValue; const State: TGridDrawStates); > var > val: Integer; > begin > // 背景色を設定 > if TryStrToInt(Value.ToString, val) then > begin > if (val mod 33) = 0 then > Canvas.Fill.Color := TAlphaColors.Red > else > Canvas.Fill.Color := TAlphaColors.White; > end; > > // 背景描画 > Canvas.FillRect(Bounds, 0, 0, [], 1); > > // テキストを描画(テキストの色や位置を調整することもできます) > Canvas.Fill.Color := TAlphaColors.Red; > Canvas.Fill.Color := TAlphaColors.White; // テキストの色 > Canvas.FillText(Bounds, Value.ToString, False, 1, [], TTextAlign.Leading, TTextAlign.Leading); > end; ***TStringGridのヘッダーカスタム描画 Delphi11.2 [[https://stackoverflow.com/questions/72892940/fmx-grid-header-lines-color]] 上記サイトからコピペ > procedure TForm4.StringGrid1DrawColumnHeader(Sender: TObject; > const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF); > var > ABrush: TStrokeBrush; > ARectF: TRectF; > begin > // fill > Canvas.Fill.Color := TAlphaColorRec.Lavender; > Canvas.FillRect(Bounds, 0, 0, [], 1); > > // draw rect, actually only bottom and right side of current header cell > ABrush := TStrokeBrush.Create( TBrushKind.Solid , TAlphaColorRec.Red); > try > Canvas.DrawRectSides(Bounds, 0, 0, [], 1, [TSide.Bottom, TSide.Right], ABrush, TCornerType.Round); > > // Draw header text > ARectF := Bounds; > ARectF.Left := ARectF.Left + 4; > Canvas.Font.Size := 15; > Canvas.Fill.Color := TAlphaColorRec.Black; > Canvas.FillText(ARectF, Column.Header , False, 1, [] , TTextAlign.Leading); > finally > ABrush.Free; > end; > end; ***IDEで表を作る VCLならColumnCount,RowCount使えばよいが、FMXには無い。 TStringGridを右クリックして「TStringColumnの追加」を行うと、桁を増やせる **証明書 XE5 認証したmacと、別のmacで開発しようとすると、XcodeのOrganizerで、こんなエラーが出る。 Organizer -> Provisioning Profiles -> Status >Valid signing identity not found 証明書を持ってこないとダメらしい。 [[2台目のMacのXcode:「Valid signing identity not found」>http://mushikago.com/i/?p=2443]] ***証明書が複数ある場合 "iPhone Developer: ambiguous"とか出た場合は、複数の証明書があって名前解決出来なかった時 [[指定された証明書名があいまい>http://docwiki.embarcadero.com/RADStudio/XE4/ja/E0264_%27%22/usr/bin/codesign%22_...%27_%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93#.E6.8C.87.E5.AE.9A.E3.81.95.E3.82.8C.E3.81.9F.E8.A8.BC.E6.98.8E.E6.9B.B8.E5.90.8D.E3.81.8C.E3.81.82.E3.81.84.E3.81.BE.E3.81.84]] ツール→オプション→環境オプション→プロビジョニング→デベロッパ証明書を、キーチェーンの名前にする。(十分一致する長さがあればいい) **iOS Developer アクティベーションに失敗した時の話 [[日本のApple StoreでiOS Developer Programを購入しActivateするまでの全スクリーンショット>http://mushikago.com/i/?p=917#step3]] **MacとWin [[delphi_mac]] **Macアプリ開発 2020-01-15 Win10 Delphi10.3 macOS Sierra 10.12.6 MacでPAServer20.0を起動 Delphi ターゲットプラットフォームをmacOS 64ビット選択 接続先は、マシン名よりもIPアドレス指定した方が安心。 接続テストはマシン名でいけても、実際の配置はIPアドレスじゃないとダメな時があった。 **Mac Retina [[ネイティブおよびカスタム FireMonkey スタイルの取り扱い>http://docwiki.embarcadero.com/RADStudio/Rio/ja/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E3%81%8A%E3%82%88%E3%81%B3%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0_FireMonkey_%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AE%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%84]] [[D: 30491, FireMonkey Premium Styles Pack for RAD Studio 10.1 and 10.2>https://cc.embarcadero.com/item/30491]] メモ Delphi10.3.3+Firemonkeyの描画おかしかったの、macOS10.12.6→10.15.2にあげたらちゃんと描画するようになった! **フォーム(デバイス)の向き(XE5) プロジェクト→オプション→アプリケーション→向き→カスタムの向き で指定する **デベロッパーキャンプ・アーカイブ [[デベロッパーキャンプ・アーカイブ>http://www.embarcadero.com/jp/developer-camp-japan/archive]] [[Delphi for iOS開発ファーストステップ>http://edn.embarcadero.com/article/images/43102/C1.pdf]] 必読 [[Windows開発者のためのFireMonkeyモバイル開発入門>http://edn.embarcadero.com/article/images/43368/a1.pdf]] 必読,iOS or ANDROID?,画面サイズと画面密度 [[モバイル開発始めるなら今でしょ!Delphi iOSアプリ開発講座>http://edn.embarcadero.com/article/images/43102/C2.pdf]] iOS配置マネージャ [[FireMonkeyファーストインプレッション>http://edn.embarcadero.com/jp/article/images/42116/T4.pdf]] パスの作成方法。VCLコンポーネントとの相違点とか、3Dとか色々書いてあるので一読お勧め [[基礎から学ぶビジュアルAndroidアプリ開発今日からあなたもAndroidデベロッパー>http://edn.embarcadero.com/article/images/43547/c2.pdf]] 基礎から丁寧に解説。必読 **classes.dexの配置 10.1update2 昔作ったソフトが動かなかった エラーは下記 >com/embarcadero/rtl/ProxyInterface が見つかりません。 で、ここらへんとか経由して [[XE10 - Java class com/embarcadero/rtl/ProxyInterface could not be found>https://forums.embarcadero.com/message.jspa?messageID=713441]] ここ [[Delphi XE8 and Seattle: Android App didn't start>https://community.embarcadero.com/forum/programming/1574-delphi-xe8-and-seattle-android-app-didn-t-start]] からのここ [[手動での classes.dex ファイルの作成と配置>http://docwiki.embarcadero.com/RADStudio/Seattle/ja/%E6%89%8B%E5%8B%95%E3%81%A7%E3%81%AE_classes.dex_%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E9%85%8D%E7%BD%AE]] 最終的にプロジェクト→配置でclasses.dexをプロジェクト下にある物を配置するように変更。 &img(classes_dex.png); **チュートリアル [[モバイル チュートリアル:Delphi モバイル アプリケーション開発(iOS および Android)>http://docwiki.embarcadero.com/RADStudio/XE5/ja/%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%EF%BC%9ADelphi_%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%EF%BC%88iOS_%E3%81%8A%E3%82%88%E3%81%B3_Android%EF%BC%89]] [[モバイル チュートリアル:リスト ボックス コンポーネントを使用してテーブル ビューを表示する(iOS および Android)>http://docwiki.embarcadero.com/RADStudio/XE5/ja/%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%EF%BC%9A%E3%83%AA%E3%82%B9%E3%83%88_%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9_%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB_%E3%83%93%E3%83%A5%E3%83%BC%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%EF%BC%88iOS_%E3%81%8A%E3%82%88%E3%81%B3_Android%EF%BC%89]] **Androidログビューア シリアルゲームズ製 [[android log viewer>http://www.serialgames.co.jp/androidlogviewer/manual/ja-jp/index.html]] **リンク [[Delphi XE3 FireMonkey変更点>http://worktoolsmith.com/2012/09/delphi-xe3-firemonkey%E5%A4%89%E6%9B%B4%E7%82%B9/]] [[delphi maniacs FireMonkey>http://delphimaniacs.blogspot.jp/search/label/FireMonkey]] [[全力わはー TMessageManagerってこんなの。>http://d.hatena.ne.jp/tales/20130622/1371894728]] [[Delphi (FireMonkey) によるテクニック&アルゴリズム>http://ht-deko.minim.ne.jp/techalgof.html]] [[想いが星空を巡る頃 Delphi XE2、FireMonkeyのCanvas描画サンプル>http://blogs.dion.ne.jp/herpuretears/archives/10373331.html]] [[VCL 利用者が FireMonkey を使う時に陥る罠5選>https://qiita.com/pik/items/1e6c8a9cdf96bc0104f3]] [[FireMonkey: 設計時、スタイルにアニメーション効果を適用する>http://edn.embarcadero.com/jp/article/42278]] [[FireMonkey - Androidアプリの[Back]キーとライフサイクル>http://blogs.embarcadero.com/teamj/2013/09/27/4065/]] [[FireMonkey Premium Style Pack 3 for RAD Studio XE5 が公開されました>http://blogs.embarcadero.com/teamj/2013/09/26/4061/]] [[Delphi モバイル コンパイラでの自動参照カウント>http://docwiki.embarcadero.com/RADStudio/XE4/ja/Delphi_%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%81%A7%E3%81%AE%E8%87%AA%E5%8B%95%E5%8F%82%E7%85%A7%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88]] うーむ、どうなんだろ [[http://ht-deko.minim.ne.jp/Delphi/index.html]] dekoさんがまとめている情報。便利〜 [[全力わはー TMessageManagerってこんなの。>http://d.hatena.ne.jp/tales/20130622]]
2024-09-13 04:04:00 32400