Jump to content

A.M. Hoornweg

  • Content Count

  • Joined

  • Last visited

  • Days Won


A.M. Hoornweg last won the day on January 26

A.M. Hoornweg had the most liked content!

Community Reputation

56 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. A.M. Hoornweg

    tContainedObject, tAggregatedObject

    Okay, that makes sense; so if I use tAggregatedObject then I can use the "AS" keyword to freely switch between the inner and the outer interface (see example 1) whereas in tContainedObject that isn't possible (it would only let me switch from the outer to the inner interface, right?) .
  2. A.M. Hoornweg

    Regex Validate string

    In my experience, when reporting is done on oil wells in the Middle East, the Arabic text is often interspersed with English technical terms. And for a developer it is quite a challenge to get mixed LTR-RTL text input right.
  3. A.M. Hoornweg

    tContainedObject, tAggregatedObject

    But tAggregatedObject doesn't DO the reference counting, it lets the controller (the owner) do that. And the controller explicitly manages the inner object's lifetime, not through reference counting. function TAggregatedObject._AddRef: Integer; begin Result := FController._AddRef; end; And when using a plain vanilla tObject (my examples 2 and 3), the owner ALSO does the reference counting. Same thing, but faster (since the _addref isn't chained). So I still don't see what tAggregatedObject is actually meant for, what problem it is supposed to solve!
  4. A.M. Hoornweg

    tContainedObject, tAggregatedObject

    COM is not the problem, I've been implementing COM objects for years. My question is really specific about the correct use and usefulness of tAggregatedObject and tContainedObject, because as far as I can see they are not needed at all to build aggregates, tInterfacedobject can already do so using ordinary tObjects. So I'm probably missing something essential about their use and usefulness! For example, this aggregate uses a tAggregatedObject: type iHello = interface ['{58AD07B9-FCE5-494A-94B2-E1CAF7D05B1D}'] procedure Hello; end; iGoodbye = interface ['{35079C32-AF3D-4E9D-808C-6A6DDED38663}'] procedure Goodbye; end; tAggregate = class(taggregatedobject, iHello) procedure Hello; end; tCompositeObject1 = class(tinterfacedobject, iHello, iGoodbye) protected ainner: tAggregate; function GetInner: iHello; public procedure Goodbye; destructor Destroy; override; property Inner: iHello read GetInner implements iHello; end; procedure tAggregate.Hello; begin messagebox(0, pchar('Hello'), pchar('Hello'), mb_ok); end; destructor tCompositeObject1.Destroy; begin messagebox(0, pchar('Destructor'), pchar('tCompositeObject1'), mb_ok); ainner.free; inherited; end; function tCompositeObject1.GetInner: iHello; begin if not assigned(ainner) then ainner := tAggregate.create(self); result := ainner; end; procedure tCompositeObject1.Goodbye; begin messagebox(0, pchar('Goodbye'), pchar('Goodbye'), mb_ok); end; procedure TestCode1; var Hello: iHello; Goodbye: iGoodbye; begin Goodbye := tCompositeObject1.create; Goodbye.Goodbye; Hello := Goodbye as iHello; Hello.Hello; end; ... and this one does the very same thing using a plain vanilla tObject: type iHello = interface ['{58AD07B9-FCE5-494A-94B2-E1CAF7D05B1D}'] procedure Hello; end; iGoodbye = interface ['{35079C32-AF3D-4E9D-808C-6A6DDED38663}'] procedure Goodbye; end; tSimpleObject = class procedure Hello; end; tCompositeObject2 = class(tinterfacedobject, iHello, iGoodbye) protected ainner: tSimpleObject; function GetInner: tSimpleObject; public procedure Goodbye; destructor Destroy; override; property Inner: tSimpleObject read GetInner implements iHello; end; procedure tSimpleObject.Hello; begin messagebox(0, pchar('Hello'), pchar('Hello'), mb_ok); end; destructor tCompositeObject2.Destroy; begin messagebox(0, pchar('Destructor'), pchar('tCompositeObject2'), mb_ok); ainner.free; inherited; end; function tCompositeObject2.GetInner: tSimpleObject; begin if not assigned(ainner) then ainner := tSimpleObject.create; result := ainner; end; procedure tCompositeObject2.Goodbye; begin messagebox(0, pchar('Goodbye'), pchar('Goodbye'), mb_ok); end; procedure TestCode2; var Hello: iHello; Goodbye: iGoodbye; begin Hello := tCompositeObject2.create; Hello.Hello; Goodbye := Hello as iGoodbye; Goodbye.Goodbye; end So is there any advantage in using tAggregatedObject / tcontainedobject at all ? I currently see more advantages in using tObject, because that allows me to take an existing class and encapsulate it inside a wrapper class whenever I want it to be interface based. For example, these few lines of code make a tStringlist interface-based, expose the methods add, get and put and make the whole thing reference counted: type // Just expose a selected bunch of methods of tStrings iStrings = interface ['{242798EB-0A53-4284-BA16-306FF354E2AC}'] function Add(const S: string): Integer; function Get(Index: Integer): string; procedure Put(Index: Integer; const S: string); property Strings[index: Integer]: string read Get write Put; default; end; tInterfacedStrings = class(tinterfacedobject, iStrings) protected fList: tStringlist; function getList: tStringlist; public destructor Destroy; override; property list: tStringlist read getList implements iStrings; end; destructor tInterfacedStrings.Destroy; begin fList.free; inherited; end; function tInterfacedStrings.getList: tStringlist; begin if not assigned(fList) then fList := tStringlist.create; result := fList; end;
  5. A.M. Hoornweg

    tContainedObject, tAggregatedObject

    Hello all, does anyone have any links to documentation/examples about the correct use of tContainedObject and tAggregatedObject? I find the little documentation I can find rather confusing. Kind regards, Arthur
  6. A.M. Hoornweg

    Sydney, debugger not working on Ubuntu LTS 20.04

    I have re-installed Delphi 10.4 after thoroughly cleaning my hard drive and registry from older Delphi 10.x leftovers and now it works.
  7. A.M. Hoornweg

    Cannot run sample programs on Android

    It wouldn't work. I have de-installed Delphi Sydney and deleted all Embarcadero folders and registry keys plus everything that had to do with Java and Android. Then I re-installed Delphi and now the compiler deploys the executable as expected. The executable won't start on Bluestacks 4 (screen stays black), however, so I'll try a hardware device next.
  8. A.M. Hoornweg

    Cannot run sample programs on Android

    I would be totally grateful if you'd tell me how to do that! I'm an absolute beginner with Android.
  9. A.M. Hoornweg

    Cannot run sample programs on Android

    Deleting the xml file makes no difference. It gets re-created, yes, and then I get the exact same error messages as before. And then Delphi hangs completely, I have to shoot it down in the task manager. All in all, deploying to Android seems unfunctional.
  10. Hello all, I'm totally new to Android, and so far I'm having zero success getting Embarcadero's sample programs to run on Android. I am running Delphi 10.4 inside a VMWare VM. On my host machine, I have the Bluestacks emulator running, with ADB debugging enabled. Connection details: I am aware that Bluestacks only binds to localhost ( so I have setup a port forwarding on the host (netsh interface portproxy add v4tov4 listenport=5556 connectaddress= connectport=5555) so that I can connect to the emulator from external IP addresses through TCP port 5556. I have enabled both ports 5555 and 5556 in the firewall. I have tested this setup and I can successfully connect to the emulator from my Delphi VM ("adb connect ip-address:5556") and send adb commands to it. I had expected this connectivity to be the biggest hurdle but it worked immediately. I have cloned Embarcadero's official sample repository from github (https://github.com/Embarcadero/RADStudio10.4Demos.git) and now I'm trying to compile and run the application in "Samples\Object Pascal\Multi-Device Samples\User Interface\Forms". I've activated the Android 32-bit target (guessing that Bluestacks emulates a 32 bit device) and the Delphi IDE "sees" the device without problems (see screenshot), it's called "SM-G973F". Since this is an "official" demo application, I was hoping things would work out of the box so I could use it as a starting point! But when I press F9, Delphi does a lengthy compiling act, and then throws the following errors: [PAClient Error] Error: E2312 Unable to execute '"C:\Users\Public\Documents\Embarcadero\Studio\21.0\PlatformSDKs\android-sdk-windows\build-tools\28.0.2\Aapt.exe" package -f -M "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\AndroidManifest.xml" -F "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\bin\Forms-unsigned.apk" -I "C:\Users\Public\Documents\Embarcadero\Studio\21.0\PlatformSDKs\android-sdk-windows\platforms\android-26\android.jar" -S "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\res" -A "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\assets" "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\library" "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\classes"' (Error 1) [PAClient Error] Error: E2312 C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\Multi-Device Samples\User Interface\Forms\Android\Debug\Forms\AndroidManifest.xml:21: error: No resource identifier found for attribute 'requestLegacyExternalStorage' in package 'android' The error messages aren't helpful at all, what the heck is "Error 1" supposed to mean? Can anyone point me to a solution? Thanks in advance, Arthur
  11. A.M. Hoornweg

    Your RAD Studio 10.4 Sydney issues

    After installing "Rad Studio 10.4 Patch (Patch Tool) Test 1.0" which recently appeared in GetIt package manager, DUnitX has disappeared from my system. How do I get it back?
  12. Hello all, when I deploy a FMX application to Ubuntu (in this case the "Screenshot" fmx demo) the Delphi 10.4 debugger hangs totally. My Windows and Linux machines are both VMWare VM's. I can see that the freshly compiled executable appears in the home/PAServer/scratch-dir/myname/Screenshot directory. The message log in the Delphi IDE gives a warning "Local file \Redist\libfmux.so not found. Skipping deployment." The executable is not started on the Linux system by PAServer. I am able to start the executable manually, so the executable itself must be OK. But Delphi hangs so thoroughly that I can't debug it. I can only terminate Delphi in the task manager. Am I doing something wrong?
  13. A.M. Hoornweg

    Can Rio and Sydney co-exist?

    Thank you all! So I'll backup my VM, enlarge the C partition and install Sydney. At a later point in time I'll uninstall Rio to free up space.
  14. A.M. Hoornweg

    Can Rio and Sydney co-exist?

    Hello all, does anyone know if Delphi 10.4 can co-exist peacefully with 10.3 Rio on the same system without one breaking the other, and can I un-install Rio later without damaging the Sydney installation? Especially if one intends to do some multi-platform (Android/Linux) work?
  15. A.M. Hoornweg

    Advice on communication between hardware

    App tethering? http://docwiki.embarcadero.com/RADStudio/Rio/en/Sharing_Data_with_Remote_Applications_Using_App_Tethering