Solution to iOS Delphi build failure

Some Delphi users building iOS applications have been thwarted by a…, well let’s be polite and call it a bit of an annoyance, when building their applications. What should just be an informational message about a warning from the ld linker ends up becoming a build breaker. The failure message looks something like this example (taken from RSP-19759, reported in January 2018):[DCC Error] E2597 ld: warning: unknown dwarf DW_FORM_strp (offset=0xFFFFCEE7) is too big in FBSDKShareKit.a(FBSDKAppInviteContent.o) ld: warning: unknown dwarf DW_FORM_strp (offset=0xFFFF6E38) is too big in C:\Dev\lib\ios\facebook\FBSDKShareKit.framework\FBSDKShareKit.a (FBSDKAppInviteContent.o)The fact that ld is emitting a warning about something is neither here not there. Or rather it *should* be neither here nor there. Unfortunately when Delphi receives this warning it turns it into a fatal error.Oh dear… (・_・、)Delphi 10.3 Rio contains a change to address this issue…. ˚◡˚Unfortunately, however, Embarcadero forgot to mention it to anyone ¯\_(ツ)_/¯This post tries to fix that communications oversight by covering the details of the change, which is an important step as you do need to add in a new compiler / linker switch.The iOS ld linker now supports a new option –bequiet, which stops Delphi being able to wrongly interpret the ld warnings (by silencing them).To use the new option choose Project | Options…  (Shift+Ctrl+F11) and do one of these two things:select Building | Delphi Compiler | Compiling | Other Options and add --linker-option:-bequiet to Additional options to pass to the compiler, orselect Building | Delphi Compiler | Linking and add -bequiet to Options passed to the LD linkerYou should now be able to build your project successfully without this little hindrance.Good luck!
Read More

android – How to release a Firemonkey control properly, in this case a child form with a parent? – Stack Overflow

For my archive as [Archive.is] TFmxObject.Release is deprecated since Delphi 10.2 Tokyo, and – worse – broken on some platforms: [WayBack] android – How to release a Firemonkey control properly, in this case a child form with a parent? – Stack Overflow TFmxObject.Release uses TThread.ForceQueue internally, and that’s currently broken under Android (see discussion above). As a workaround, a working cross-platform version for releasing an object from its event handler would be procedure TForm.CloseBtnClick(Sender: TObject); begin Parent := nil; TThread.CreateAnonymousThread( procedure begin TThread.Synchronize(nil, procedure begin Self.DisposeOf; end); end).Start; end; Instead of Synchronize you can also use Queue in above method. What is important to keep in mind is that you should not keep any other references to the control you are releasing or you may hit the trouble down the road. Dalija Prasnikar Via: [WayBack] What are the solutions for a wizard like application (a single form with content changed depending on some action) in Firemonkey? I’ve been using TFormStand to have a single form and load frames dynamically, but have some AV in the stept when changing frames…. – R Gosp – Google+ –jeroen
Read More

Delphi: AutoSize property resizes a container (panel, scrollbox, form, frame…) to grow it to fit all controls

A while back I needed a design-time way to automatically resize a Delphi container control (descendants from the, [WayBack] TWinControl Class like [WayBack] TPanel, [WayBack] TScrollbox, [WayBack] TForm, [WayBack] TFrame) to grow/shrink so it just fits around it’s contained controls. Back then I needed it for VCL design time, if possible taking into account non-visual components. The [WayBack] TControl.AutoSize Property does just that for visual controls and works way better than suggestions on doing this manually. Manually adjusting many controls at design time is a tedious job, especially when trying to prevent mouse usage (I’ve had RSI in the early 1990s, so I’m extra careful). Thanks Uwe Raabe for helping me out on this. I’ve not had the need for non-visual components or FMX yet, but if I ever need it, then this piece of code by Stefan Glienke might work: [Archive.is] [Delphi] ResizeControlEditor – Pastebin.com –jeroen Source: [WayBack] Is there an expert that can resize a container (panel, scrollbox, form, frame, etc) to be just large enough so it fits all it components?So: grow when… – Jeroen Wiert Pluimers – Google+ https://pastebin.com/vT0FnRPN    
Read More

What’s In RAD Studio 10.3 Architect Edition?

Since the early days, Delphi and RAD Studio have always been distributed in different editions, which occasionally change over time. During the last year, we have redefined all of the editions of RAD Studio, creating a new offer. Delphi, C++Builder, and RAD Studio Versions We introduced the Community Edition, which is free for non-professional use (read the EULA for more details) and a great tool for students, hobbyist, and other developers who want to learn ho to sue Delphi or C++Builder We expanded the Professional Edition including mobile support, so that now professional targets 4 different client platforms We have added to the Enterprise Edition the ability to deploy RAD Server solutions on one site and deployment on mobile of IBToGo (embedded InterBase with encryption) What is in Architect Edition? The largest changes, though, are for the Architect edition. In terms of core product, the Architect edition is identical to the Enterprise one. In fact when you install RAD Studio Architect you are in fact installing RAD Studio Enterprise. So what additional value are you getting for the higher price point? The Architect edition is a bundle of additional licenses and software products: The bundle includes a RAD Server multi-site licenses, meaning you can deploy your RAD Server solutions on unlimited servers and physical locations A license of AquaFold Aqua Data Studio for general database management across all of your databases and platforms A license of Sencha Ext JS Professional Edition for building Web clients (for example, an HTML and JavaScript client for your RAD Server services) A time limited license of Ranorex Test Automation for testing the UI of your Delphi Windows applications These licenses are included in new purchases, and the RAD Server, Aqua Data Studio and Sencha Ext JS ones are also made available to customers on update subscription -- while Ranorex Studio is available only for customers buying a new license of RAD Studio, Delphi, or C++Builder Architect. Architect Webinar Today To learn more about these products, you can follow a webinar later today that I'm giving with the help of experts of the different products, "Getting Ahead with 10.3 Architect Edition". Register now at https://register.gotowebinar.com/register/1263861523722391299. The webinar is today at 12 noon Central US time, which is 7 PM Central European time. Replays will be made available.    
Read More

Conditional compilation for various Delphi versions

If you are maintaining a library, component or plugin for various Delphi versions you will sooner or later hit a point where it becomes necessary to have different code for some of them. Some examples are: The constants faTemporary and faSymlink are only declared in Delphi 2009 and later, so you have to declare them yourself for older versions. Some Open Tools API function have bugs in some versions so you have to implement a workaround. Some classes or functions have been added to later versions of the RTL so you need to implement them yourself for older versions, but you don’t want to use these implementations for newer versions The traditional way of masking code for some Delphi versions is using the VERxxx symbols which the compiler defines, where xxx is the compiler version multiplied by 10. Note that the compiler versions started with Turbo Pascal, not with Delphi, so VER60 is not Delphi 6 but Turbo Pascal 6, while Delphi 6 is compiler version 14 and therefore defines VER140. By the time of this writing the current Delphi version is 10.3 Rio which contains the compiler version 33. {$IFDEF VER330} // Delphi 10.3 Rio // do some version specific stuff here {$ENDIF} There are various include files that make this more convenient by adding symbols like DELPHInn and DELPHInn_UP so you don’t have to memorize those VERxxx symbols. {$IFDEF DelphiX103} // do some version specific stuff here {$ENDIF} But using these include files has got a major drawback: If you forget to include it into your source code, all your IFDEFS will fail and in the worst case your workaround won’t be active (the best case is that the compiler runs into an error so you will notice the missing include). An alternative is the {$IF } compiler directive which can test for arbitrary Boolean expressions, like const SomeConstantValue = 5; //later on {$IF SomeConstantValue >= 5} // do some stuff here that requires SomeConstValue to be at least 5 {$ENDIF} It was added to the Delphi compiler in Delphi 6, so it covers quite a few Delphi versions. Combined with predefined constants (in the System unit) like CompilerVersion RtlVersion FireMonkeyVersion (in FMX.Types) this is a powerful method for conditional compilation. {$IF CompilerVersion = 330} // Delphi 10.3 Rio // do some version specific stuff here {$ENDIF} It can also replace those additional symbols DELPHInn_UP I mentioned above: “>=” replaces {$IFDEF DELPHInn_UP} and “=” you can “future proof” your code, assuming that code for Delphi 10.3 Rio will also work with all newer versions of Delphi. {$IF CompilerVersion >= 330} // Delphi 10.3 Rio // do some version specific stuff here that will // hopefully also work in the future {$ENDIF} But unfortunately we are back to memorizing compiler and RTL version constants. Even with tools like the IF Directive Expert in GExperts this is a nuisance because if you forget to add a comment (or if you later change the expression and forget to update the comment), you will still have to know those values to understand the code. So, what can be done? An idea that occurred to me today (Yes, I am a bit slow on creativity.) would be to define additional constants which can then be used to compare against the CompilerVersion and RtlVersion constants. unit CompilerAndRtlVersions; interface const CompilerVersionDelphi6 = 14; CompilerVersionDelphi7 = 15; // we all want to forget Delphi 8, but it had compiler version 16 CompilerVersionDelphi2005 = 17; CompilerVersionDelphi2006 = 18; CompilerVersionDelphi2007 = 18.5; // anybody remember Delphi 2007 for dotNET? That one had compiler version 19 CompilerVersionDelphi2009 = 20; // and so on until CompilerVersionDelphiRio = 33; // and of course we would also need the RtlVersions: const RtlVersionDelphi6 = 14; RtlVersionDelphi7 = 15; // and so on until RtlVersionDelphiRio = 33; implementation end. Add the above unit to the uses clause and you can do: {$IF CompilerVersion >= CompilerVersionDelphiRio} // do some version specific stuff here {$ENDIF} These constants should go into a unit rather into an include file so the compiler will complain if you forget to add that unit to the uses clause. In addition a unit will be compiled once and afterwards the compiler will use the DCU file it created, while an include fill will be parsed every single time it is included. This should speed up compilation a (probably tiny) bit. I am not aware if such a unit already exists, but I would probably write it and make it available if not (it’s not excactly rocket science after all). Edit: Here you go, my brand new u_dzCompilerAndRtlVersions unit. I already blogged about using and ab-using ifdef in 2013, if you are interested in this topic.
Read More

New Delphi 10.3 Warning "Unknown Custom Attribute"

Up to Delphi 102, if you used a custom attribute that was not known to the compiler (because you typed it incorrectly or a unit was missing in the uses statement), you'd receive the warning: Warning: W1025 Unsupported language feature: 'custom attribute' This message was misleading, because the feature has been in the language for quite some time, it was just using an undefined symbol in it. There is a large list of reports on this issue, including https://quality.embarcadero.com/browse/RSP-20384.  Starting with 10.3, the same code will trigger a new specific warning: Warning: W1074 Unknown custom attribute This conveys a more specific information. It also makes it is easier to turn this warning into an error -- which would often make sense, by using the directive: {$WARN UNKNOWN_CUSTOM_ATTRIBUTE ERROR} In the past you could achieve the same by turning the unsupported language feature warnings into errors, but that could have included also other unwanted scenarios.
Read More

Delphi RTL Improvements in 10.3 Rio

While working on 10.2 updates, we started delving into some performance issues of the Delphi RTL, that were effecting other libraries like JSON processing, streaming, string processing, DataSnap and RAD Server web services, and more. In many cases, addressing these issues required adding new methods to existing classes, or adding new global functions, something we can do only in interface breaking releases like 10.3. Optimization and performance was a guiding factor to many of the changes listed below, but not the only element. We also wanted to update external libraries, improve conformance to standards like JSON and HTTP, and improve quality overall. With this scenario in mind, the list of improvements is fairly long (and a bit boring, sorry). Change in Data Structures Growth Strategy Several data structures (like TStringList, TList, TList , TQueue and TStack) have now a flexible growth strategy when the internal storage is full and needs to be expanded after adding an additional item. In the past, the strategy was to double the size of the underlying structure, something that works fine for smaller sizes, but not when you have several MB of storage. Now the rules is to increase capacity by 1.5 times. For example you can check a TStringList growth by checking the Capacity property, which now grows as follows (from 14K to 74K): 14,761 22,141 33,211 49,816 74,724 This behavior, shared by multiple collection classes, is defined in the new function, declared in SysUtils.pas: function GrowCollection(OldCapacity, NewCount: Integer): Integer; Now the interesting element is that the implementation can be replaced with a custom function growth strategy, by writing a new compatible function and calling the global SetGrowCollectionFunc procedure.  Changes in TStringBuilder Class The TStringBuilder class has had several changes with the goal of improving its performance, including a similar change in memory growth strategy, the removal of some redundant code, and an overall implementation cleanup. The TStringBuilder enumerator has been optimized, however it expects that the TStringBuilder object will be not modified while the enumerator is processing it (which is a common behavior for enumerations). There is also an additional parameter for the TStringBuilder.ToString method. The signature is ToString (UpdateCapacity: Boolean). ToString(True) will give better performance if no more modifications expected for TStringBuilder, as it reduces the amount of data being copied. Lists-Related Improvements There are other improvements related with lists and collections. The generic TList and the generic TDictionary have new public properties to make their comparers (the definition of their comparison operations for sorting) accessible after initialization. We've added a TryAdd method to TDictionary, an ExtractAt to TObjectList and significantly improved the performance of several operations (IndexOf, Add, and more). We have also specifically optimized for-in loops for generic collections and string lists, with an empty "for in" loop about 3 times faster  JSON-Related Improvements In 10.3 we have improved the correctness of JSON content, in terms of the JSON code generated by the TJSONValue class and derived ones, but also in terms of parsing. We have also worked on performance improvements. There is a new TAsciiStreamWriter class that can be combined with a TJSONTextWriter to give the best JSON string generation performance (as it does almost no conversion at all). There is now “pretty print” JSON output with the introduction of the new TJSONAncestor.Format(Indentation: Integer = 4). As a consequence, TJSON.Format has been deprecated. We have also clarified (and properly implemented) the difference between calling ToJSON and ToString for a JSON object: TJSONAncestor.ToJSON always produces a formally valid JSON string TJSONAncestor.ToString produces a similar JSON string, but without converting non-ASCII symbols to \uNNNN (faster, but not formally valid) JSON parsing support has a new behavior in case of errors in the JSON source text, allowing you to raise an exception with information about the error position in the source text, rather than just returning nil. The new option controlling the behavior is TJSONParseOption.RaiseExc. If the exception is enabled, ParseJSONValue raises the new System.JSON.EJSONParseException (which has the properties Path, Offset, Line, and Position). Additionally, the method TJSONObject.ParseJSONValue has a third new parameter: RaiseExc, which overrides the global setting causing the exception to be raised, in case of JSON parsing errors. TMemIniFile Class Improvements In Delphi 10.3 we have optimized the TMemIniFile implementation. Reading and constructing a TMemIniFile is 10 to 25 times faster and consumes half of the memory. Other TMemIniFile operations are improved too and they are 50 to 100% faster compared to the previous implementation. We have also added the ability to load a TMemIniFile from a stream, with two additional overloaded constructors: TMemIniFile.Create(Stream) and TMemIniFile.Create(Stream, UseLocale). These constructors parameters remain available in the class and are exposed in new properties, Stream and UseLocale. External Libraries Updates (zLib, PCRE, Unicode) We have done some improvements to external libraries we incorporate: zlib has been upgraded to version 1.2.11 1.2.8 with additional fixes (and it is now compiled with RAD Studio C++ compiler for 64-bit) The regular expression engine, PCRE, has been upgraded to 8.42 (and also now compiled with RAD Studio C++ compiler), and supports the UTF-16 native version on Windows (to reduce the conversions from UTF-16 string to UTF-8 strings). The Unicode table (System.Character unit) supports Unicode v11.0. A Lot Was Done in 10.3 for Delphi RTL As you can see the number of improvements in Delphi RTL for 10.3 Rio is fairly significant, not to mention the work focused on fixing bugs and improving quality. There is more for the HTTP and other client libraries, which I'll cover in a separate blog post.
Read More

Found the cause of the AV on exiting the Delphi IDE

There was a bug in the (yet unreleased) GExperts code that caused an access violation every time the Delphi IDE was closed. I have just found it, but boy was that difficult! I knew the problem existed in the current source code and by trial and error I found a source code revision that did not yet have it: #2415. So I compared those revisions and step by step narrowed it down to the changes in the unit GX_IdeFormChangeManager in revision #2433 which was a fix for a redrawing bug in the Delphi 10.2 Search Path dialog. So I removed the code I had added, which consisted of two parts: procedure TFormChangeManagerInternal.ProcessActivatedForm(Form: TCustomForm); var i: Integer; NeedsWorkaround: Boolean; begin Assert(Assigned(Form)); // We are executing the callbacks in last registered first order to allow callbacks to // unregister themselves. (And we don't check whether a callback only unregisters itself, so // please be cautios!). That means registering a new callback while executing a callback // is not allowed. FIsInFormChangeCallback := True; try // ------------- workaround part 1 starts here ------------ // Workaround for redraw issue in Delphi 10.2 when theming is enabled: // https://sourceforge.net/p/gexperts/bugs/86/ // Disable redraws while we change the window NeedsWorkaround := HasRedrawProblems(Form); if NeedsWorkaround then SendMessage(Form.Handle, WM_SETREDRAW, WParam(False), 0); // ------------- workaround part 1 ends here ------------ try for i := FFormChangeCallbacks.Count - 1 downto 0 do begin try TFormChangeCallbackItem(FFormChangeCallbacks[i]).FCallback(Self, Form); except // just so we can have a look at any exceptions that might be raised ... raise; end; end; finally // ------------- workaround part 2 starts here ------------ if NeedsWorkaround then begin // Allow and force a redraw of the whole window SendMessage(Form.Handle, WM_SETREDRAW, WParam(True), 0); RedrawWindow(Form.Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN); // see Remarks on // https://docs.microsoft.com/en-us/windows/desktop/gdi/wm-setredraw end; // ------------- workaround part 2 ends here ------------ end; finally FIsInFormChangeCallback := False; end; end; I didn’t really think this could make a difference because the HasRedrawProblems function only returns true in Delphi 10.2 but the AV occurred in all versions of the IDE. And guess what? It didn’t make a difference at all! The AV still happened. So I reverted all the changes to the unit, which included the addition of a few units to the uses clause in the implementation section: Messages, Registry and GX_IdeSearchPathEnhancer The AV was gone! Now what? I added Messages and Registry again, everything still was fine. Then I added GX_IdeSearchPathEnhancer and boom, the AV was back. After I knew what to look for, the cause was simple to spot: Both units GX_IdeSearchPathEnhancer and GX_IdeFormChangeManager have got a finalization section. They both free an instance of a class that gets created some time during the life time of a GExperts session. By adding GX_IdeSearchPathEnhancer to the uses list of GX_IdeFormChangeManager, the execution order of the finalization sections changed. The unit GX_IdeFormChangeManager provides a singleton instance of TFormChangeManagerInternal which gets created on demand in any of the class methods of TIDEFormChangeManager. That instance is freed in the finalization section. The unit GX_IdeSearchPathEnhancer has an internal instance of TSearchPathEnhancer which also gets freed in its finalization section. TSearchPathEnhancer.Create registers itself for Screen.OnActiveFormChanged events to detect when the IDE’s Sarch Path dialog is being shown. In the Destructor it unregisters itself for that event. So far, so good, now the problem occurs when the finalization of GX_IdeFormChangeManager runs before the one of GX_IdeSearchPathEnhancer: The singleton instance of TFormChangeManagerInternal gets freed and afterwards the destructor of TSearchPathEnhancer tries to use it to unregister itself from the OnActiveFormChanged event. This created a new TFormChangeManagerInternal instance which hooked the Screen.OnActiveFormChanged event. Since the finalization of GX_IdeFormChangeManager had already run, this new instance never got freed, so as soon as the GExperts DLL was unloaded, the event pointed to uninitialized memory and thus the access violation occurred. This of course will never show anything usable in the debugger as the offending code has already been unloaded. Now you might ask, why in the world I added the additional unit to the uses clause? That was because of the fix introduced in that revision. It needed to know if the new active form as the Search Path dialog, and following the Don’t repeat yourself (DRY) principle [1] of good software development, I moved the code for detecting that, which was already in a method of TSearchPathEnhancer, to a public class method of that class. So I avoided duplicating the code. but in order to call that class method, I had to add the unit to the uses clause. Which introduced the bug. Even though it was difficult to trace it, at least it was a reproducible bug, so I could finally track it down. Now I’m going to fix it and then I will start testing GExperts in Delphi 10.3 so I can make a new release. [1] Yes, it is DRY, because the knowledge of how to detect if a form is the Sarch Path dialog is “business knowledge”, in this case knowledge about what class and name that form has in any of the IDE versions.
Read More

Delphi 10.3 Rio got released; I’ll wait a while hoping to see more positive comments

The first messages on G+ saw about Delphi 10.3 Rio are these: [WayBack] Delphi 10.3 is online. – Ralf Stocker – Google+ [WayBack] The platform selection in Delphi Rio seems to be down. – Gert Scholten – Google+ [WayBack] license.embarcadero.com is down. Perhaps this is a good sign, because of overwhelming interest in Rio, but it does not make a great impression. Can thi… – Johan Bontes – Google+ [WayBack] Just installed Delphi 10.3 and used migrationtool.exe to import 10.2 settings, and my projects fail to compile with the following error (I am not even c… – Eric Grange – Google+ [WayBack] FMX minimize bug fix for Delphi Rio Community. The two screenshots show you how. https://quality.embarcadero.com/browse/RSP-17322 You at home would ne… – Gustav Schubert – Google+ [RSP-17285] Window minimize-restore via taskbar icon click is broken in all Windows flavours – Embarcadero Technologies (10.1/10.2 problem that was supposedly fixed in 10.3) [RSP-17322] Window minimize-restore via taskbar icon click is broken in all Windows flavours – Embarcadero Technologies has the fix for 10.3, but did not make it in 10.3 [WayBack] I think I figured it out and here is my unofficial update to FMX.Platform.Win ready for beta testing. Improvement claims: 1) click on task bar button w… – Gustav Schubert – Google+ [WayBack] … but I am working on it. I have already installed the new version and it compiles on my machine. But don’t hold your breath, there are some issues. Unt… – Thomas Mueller (dummzeuch) – Google+ I think I will wait a while before installing until more positive messages are being published. If you do want to try, the hashes of delphicbuilder10_3_0_94364.iso are these: crc32 157b6e36 md5 0882d58cb53a7d0a828cc45d06c6ecd0 sha1 21579b530f781895885923809d9e670b439ebf9d sha256 9213de93c2abdd6a2ee23aa84fc7e63a87d62d0344f0d0f0ee162d0e7dce7c7d ––jeroen PS: [WayBack] How to verify file hashes on macOS | ModMy
Read More

RAD Studio 10.3 Rio supports Android runtime permissions

RAD Studio 10.3 Rio has just been released for General Availability, as you’ll have doubtless learned from the spree of blog posts on the subject. This is a great new release with a lot of bug fixes and some nice updates to product behaviour and features.One feature that seems to have not received its fair share of attention in the documentation is the support for the Android 6.0 (and later) runtime permissions model. This caused a bit of frustration earlier in the year when Google changed the Play Store submission rules so that from August 2018 new apps have to follow this new permissions model and from November 2018 app updates also new apps have to.RAD Studio 10.3 enhances the basic Android support to ensure that Android apps built with Delphi or C++ now understand and can support this new model, which may require a bit of change to your application logic.In essence, instead of all permissions being granted on application installation, so-called dangerous permissions now need to be requested at runtime where the user can grant or deny them as they see fit. Additionally the user can change their mind in the app settings and toggle the permissions at any time.The Android RTL has been enhanced with a framework to support requesting permissions at runtime and being notified of the user’s decision, and potentially offering a little explanation for the need for the permission.As mentioned the documentation for this framework falls a little short right now (at product launch), but hopefully will improve over time. To try and plug the gap I’ve written an article showing how the permission framework can be used, both in Delphi and in C++. If interested in learning more about the Android runtime permission framework introduced in RAD Studio 10.3 Rio, please follow one of these links:Runtime permissions in Android (new in Delphi 10.3)Runtime permissions in Android (new in C++ 10.3)Finally, while I have your attention on things Android, I would like to draw your attention to the Android-specific release notes for RAD Studio 10.3. You should read these to be sure of getting on with your first Android project with the new product release. It needs and uses a later Android SDK and NDK and you mat encounter some teething niggles on installation. These notes should help you!
Read More