Tag: firemonkey

FMX TMemo is painfully slow

I was writing a Firemonkey application and ran into a problem: TMemo is painfully slow. It needs 12+ seconds to load a 3 mb file, VCL TMemo only needs 400 ms Here is my test code: uses System.Threading, System.Diagnostics; procedure TForm1.FormCreate(Sender: TObject); begin TTask.Run( procedure begin Sleep(100); var stopwatch := TStopwatch.Create; TThread.Synchronize(nil, procedure begin stopwatch.Start; Memo1.Lines.LoadFromFile('../../../DemoData.json'); end); TThread.Synchronize(nil, procedure begin stopwatch.Stop; Caption := stopwatch.ElapsedMilliseconds.ToString; end) end); end; The entire test project (including JSON file) can be found here: https://borrisholt.dk/Delphi/MemoDemo.zip Or your can of course use your own 3mb text file. Can anything be done or is it just the way it is with FMX?
Read More

Playing sounds as Android Service with Delphi FMX

Have a project which accumulates data from a 3 Party Device to android Tablets / Phones this is set to beep when a data packet is accepted and works fine until the App goes to the background I thought that if I Created a service to make the sound this would be over come however I have found that I cant Address the FMX components from the Service so the present way that I am implementing the sound is not available in the main app I Used procedure PlayMedia(aFile: String); var l_mp: TMediaPlayer; begin l_mp := TMediaPlayer.Create(Application); l_mp.FileName := System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetDocumentsPath, aFile); l_mp.Play; end; In the Service I Tried procedure TDMSounds.PlaySound(afile: String); var Volume: Integer; StreamType: Integer; ToneType: Integer; ToneGenerator: JToneGenerator; RingToneMgr:JRingToneManager; RingTone:JRingtone; begin Volume := TJToneGenerator.JavaClass.MAX_VOLUME; StreamType := TJAudioManager.JavaClass.STREAM_SYSTEM; ToneType := TJToneGenerator.JavaClass.TONE_DTMF_9; ToneGenerator := TJToneGenerator.JavaClass.init(StreamType, Volume); ToneGenerator.startTone(ToneType, 1000); end; carn't seem to get a result from the service any Ideas Greatly Appreciated
Read More

FMX: TScrollBar MouseDown and MouseUp events not triggering

I've created the following class to try to improve the response of a scroll bar. The reason is that if the code in the scrollbar's onchange event is even slightly slow then updates don't take effect until you stop dragging the thumb. This is annoying if redrawing a canvas in the onchange event for example. However, updating the canvas in a TTimer event is smooth. My guess is that this has something to do with the TScrollBar OnChange events being synchronous, whereas the TTimer events are asynchronous. My code attempts to solve the TScrollBar problem by triggering the event using a TTimer, which is enabled using the MouseDown event and disabled using the MouseUp event. The issue is that the OnMouseDown event doesn't trigger at all. I also tried just adding a TScrollBar component to the form at design time and then checking if its MouseDown or MouseUp events get triggered, but they don't either. I managed to find a similar question from 2013, which was never answered. https://codeverge.com/embarcadero.delphi.firemonkey/help-how-to-trap-mouse-down-mou/1057945 So is there a reason why these events are not triggered? How can I get them to trigger? Also, if there's another way to improve the response of a standard TScrollBar then please let me know? I'm using Delphi 10.4. unit ScrollBarSmoothUnit; interface uses System.Classes, System.UITypes, FMX.StdCtrls, FMX.Types; type TScrollBarSmooth = class(TScrollBar) private FTimer : TTimer; FLastValue : Single; procedure ScrollMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure ScrollMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure DoChange(Sender: TObject); public OnChangeSmooth : TNotifyEvent; constructor Create(AOwner: TComponent); override; end; implementation constructor TScrollBarSmooth.Create(AOwner: TComponent); begin inherited Create(AOwner); AutoCapture := True; HitTest := True; OnMouseDown := ScrollMouseDown; OnMouseUp := ScrollMouseUp; FTimer := TTimer.Create(Self); FTimer.Interval := 40; FTimer.Enabled := False; FTimer.OnTimer := DoChange; FLastValue := -1; end; procedure TScrollBarSmooth.ScrollMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin FTimer.Enabled := True; end; procedure TScrollBarSmooth.ScrollMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin FTimer.Enabled := False; DoChange(Self); end; procedure TScrollBarSmooth.DoChange(Sender: TObject); begin if Value = FLastValue then Exit; // No change FLastValue := Value; if Assigned(OnChangeSmooth) then OnChangeSmooth(Self); end; end.
Read More

FMX ViewPort3D performance drop when filled with a large number of 3D shapes

I have a ViewPort3D element in a multi-device application form that being filled with a large number of TRectangle3D elements (anywhere from 1 to 10000) with LightMaterialSource applied to them, which all need to be rendered dynamically since I'm also rotating the camera using the following procedure: procedure TForm3.Viewport3D1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); var I: IViewport3D; begin if ssRight in shift then begin I:=ViewPort3D1; with tdummy(I.CurrentCamera.Parent) do RotationAngle.X:=RotAng.X - Y; with tdummy(I.CurrentCamera.Parent.Parent) do RotationAngle.Y:=RotAng.Y + X; end; end; However the performance of the ViewPort3D begins to drop noticeably when the number of rectangles rendered approaches at least several dozen. The camera rotation gets slower and more unresponsive the more rectangles are added to the viewport up to the point of becoming a slideshow. Is there a way to improve performance of the ViewPort3D without deleting said rectangles? I've tried using setting the Multisample property to "none": ViewPort3d1.Context.SetMultisample(TMultisample.None) as well as removing MaterialSource from all the rectangles. While it did help a little with the performance, it didn't solve the problem entirely.
Read More

Deploying FMX Delphi Sydney 10.4.2 to IOS Simulator Error ( xcode 12.5 / IOS 14.5 )

I tried my first test to deploy a simple FMX app to the Apple world. I have MacBook Pro Intel i5 with MacOS BigSur 11.5.2 installed ( upgraded from Mojave ) and installed xcode from Apple store 12.5 ( supporting IOS 14.5 ) . Deploying to the 64bit macOS itself worked. Now I try to deploy to IOS Simulator but I got error ‘/Applications/PAServer-21.0.app/Contents/MacOS/db…’ unable to create process.
I can’t find the full error on delphi side ( not more info in output or build messages ). running the PA server in verbose gives as last command “Applications/PAServer-21.0.app/Contents/MacOS/dbkosx_27_0” – listen.

I’m new to this so unsure if these versions combinations ( MacOS BigSur 11.5.2 / XCode 12.5 / IOS 14.5 ) should work or not. And if not, what combination should work. To test, I installed IOS 13.7 support on Xcode / simulators and devices screen and created a new device. But I don’t know to get delphi downloading the SDK for this from the Mac. It’s still using IOS 14.5 SDK also for this device.
If I try to start the app directly on the mac , I get an error that seems to hint that it would be a 32bit application ????

I see that build process is using ‘dccios32.exe’ ?

Read More

Read More

Is there an equivalent in RAD Studio Delphi’s FMX for the VCL.MinimizeName function?

I am writing an app for Windows/Mac/iOS/Android and I need to find a way to minimize a long path and filename for display in a TLabel. The VCL library has a MinimizeName function for this, but VCL is not available in anything other than Windows. Is there an equivalent for this in the FireMonkey FMX libraries?
Read More

How do I announce a Bonjour service?

I am trying to implement code that announces a Bonjour service on OSX. Out of the box, there isn't a direct way to do this. In Macapi.Foundation are the following interfaces: NSNetServiceClass and NSNetService. Then there is the wrapper class TNSNetService. These are the interfaces and class that should let me announce a service. In my class TsdBonjourAnnouncerMac, I have an activate() method which announces the service. I followed the same code template as creating a Bonjour listener, which works fine. However this code crashes. The line of code INetService := TNSNetService.Wrap(TNSNetService.OCClass.alloc); is raising an Access Violation. TNSNetService.OCClass.alloc is the offender. I don't know how to fix this. I found this: Using OS X APIs directly from Delphi. It shows a slightly different process. I tried using it, but was not able to call any of the methods in NSNetService since they aren't class methods. How can I get this to work? NSNetServiceClass = interface(NSObjectClass) ['{450D03AC-1380-44BA-B4C3-2D30DACACA43}'] {class} function dataFromTXTRecordDictionary(txtDictionary: NSDictionary): NSData; cdecl; {class} function dictionaryFromTXTRecordData(txtData: NSData): NSDictionary; cdecl; end; NSNetService = interface(NSObject) ['{8FACC18E-5DFA-4526-A256-DBD7CF74B65C}'] function TXTRecordData: NSData; cdecl; function addresses: NSArray; cdecl; function delegate: NSNetServiceDelegate; cdecl; function domain: NSString; cdecl; function getInputStream(inputStream: NSInputStream; outputStream: NSOutputStream): Boolean; cdecl; function hostName: NSString; cdecl; function name: NSString; cdecl; function port: NSInteger; cdecl; function protocolSpecificInformation: NSString; cdecl; procedure publish; cdecl; procedure publishWithOptions(options: NSNetServiceOptions); cdecl; procedure removeFromRunLoop(aRunLoop: NSRunLoop; forMode: NSString); cdecl; procedure resolve; cdecl; procedure resolveWithTimeout(timeout: NSTimeInterval); cdecl; procedure scheduleInRunLoop(aRunLoop: NSRunLoop; forMode: NSString); cdecl; procedure setDelegate(delegate: NSNetServiceDelegate); cdecl; procedure setProtocolSpecificInformation(specificInformation: NSString); cdecl; function setTXTRecordData(recordData: NSData): Boolean; cdecl; procedure startMonitoring; cdecl; procedure stop; cdecl; procedure stopMonitoring; cdecl; end; TNSNetService = class(TOCGenericImport<NSNetServiceClass, NSNetService>) end; //****************************************************************************// TsdBonjourAnnouncerMac = class(TsdBonjourAnnouncerBase) private IDelegate: NSNetServiceDelegate; INetService: NSNetService; protected function Activate: Boolean; override; procedure DeActivate; override; public end; function TsdBonjourAnnouncerMac.Activate: Boolean; begin inherited; Result := True; INetService := TNSNetService.Wrap(TNSNetService.OCClass.alloc); // Raises access violation // More code to initialize // Set the delegate IDelegate := TsdServiceDelegate.Create; INetService.setDelegate(NSNetServiceDelegate((IDelegate as ILocalObject).GetObjectID)); INetService.publish; end; procedure TsdBonjourAnnouncerMac.DeActivate; begin end;
Read More

C++ Builder with Firemonkey for mobile app examples and training [closed]

I am considering C++ Builder with Firemonkey for building a regular mobile app targetting IOS and Android. The mobile app will interact mostly with a Rest-JSON-Backend API. While I found a lot of examples, and training courses including Delphi with Firemonkey, I was not able to find much about C++ with Firemonkey. I would appreciate your comment to put me on the right path. Learning Delphi would be difficult at the moment.
Read More

How to let Parent component get click events of child components?

I have a FireMonkey application with multiple buttons on it (actually, rectangles). I want to have one procedure called on any click on the Form, besides the specific action of each button. Since the HitTest of each child component is set to True, the parent's HitTest is automatically false. So what is the right way to deal with this? A silly workaround would be to assign this procedure to each button's OnClick event, but this will not make any sense when I have a Form with hundreds of buttons on it.
Read More

Firemonkey Android InputStream reads 0s for files larger than 1MB

My Firemonkey Android app launches for multiple file types including zip files. When I check the intent and try to read the file that launched my app, I read 0s for files over 1MB. I don't know the exact size limits. A 1.7KB file reads correctly, a 1.36MB file does not. It reads the correct number of bytes, and after reading 0s for about 2/3s of the file, it finally starts reading actual file data from the beginning of the file. This is my first attempt at such things. I created simplified test code to explore the problem: function StartupFileGet : string; var intent: JIntent; uri: Jnet_Uri; uriStr: String; InStrm: Androidapi.Jni.Javatypes.JInputStream; ch: Char; total: integer; begin result := ''; intent := TAndroidHelper.Activity.getIntent; if intent <> nil then begin if TJIntent.JavaClass.ACTION_VIEW.equals(intent.getAction) then begin uri := intent.getData; uriStr := JStringToString(uri.toString); result := uriStr; result := result + '='; InStrm := TAndroidHelper.Activity.getContentResolver().openInputStream(uri); if InStrm <> nil then begin total := InStrm.available; if total > 0 then begin try ch := Char(InStrm.read()); if ch = #0 then ch := #$30; result := result + ch; ch := Char(InStrm.read()); if ch = #0 then ch := #$30; result := result + ch; except result := result + ', exception'; end; result := result + ', '; result := result + IntToStr(total); end; end; InStrm.close; end; end; end; Incorrect result with a 1.36MB zip file is: Startup file: content://com.google.android.apps.nbu.files.provider/2/1044=00, 1362165 Correct result with a 1.7KB zip file is: Startup file: content://com.google.android.apps.nbu.files.provider/2/1045=PK, 1697 In both the above results, the file sizes are correct. Android 9, both files are in the downloads folder. Rad Studio 10.4.1
Read More

How the app icon is added inside my iOS app?

When I look my Info.plist their is nothing about icon in it, but after I deployed the app, I look in it for the the Info.plist and I can see that it's contain : <key>CFBundleIcons</key> <dict> <key>CFBundlePrimaryIcon</key> <dict> <key>CFBundleIconFiles</key> <array> <string>AppIcon60x60</string> </array> <key>CFBundleIconName</key> <string>AppIcon</string> </dict> </dict> <key>CFBundleIcons~ipad</key> <dict> <key>CFBundlePrimaryIcon</key> <dict> <key>CFBundleIconFiles</key> <array> <string>AppIcon60x60</string> <string>AppIcon76x76</string> </array> <key>CFBundleIconName</key> <string>AppIcon</string> </dict> </dict> I can see that also the root folder of my app contain 2 files : AppIcon60x60@2x.png AppIcon76x76@2x~ipad.png but nothing in my project, in deployment option, is speaking about those 2 icons. so where they are coming from ? what process add the CFBundleIconFiles key value to the info.plist ? I want to specify myself the icon (and not from the ide of delphi, I want to update myself the info.plist, and i want to deploy myself the icon), how can I do ?
Read More