Delphi - How to correctly register a graphic class since XE8? - delphi

I'm writing a Delphi package, which provides a new custom TGraphic object, allowing to read a new image format in VCL components like TImage.
I originally developed this package with RAD Studio XE7, and it worked well. However I migrated recently to a newer RAD Studio compiler version, and although my package continues to work properly on that new version, I noticed a strange bug that never appeared before.
I have a form with several components, some of them are TImage components. Immediately after opening the IDE, the first time I open my project in design time, all the TImage components containing my custom TGraphic component loose their content. If I close then reopen the project, the images reappear, and the bug no longer happen until I close and reopen my IDE.
I dug in my code to understand what may cause the issue. To register my custom TGraphic component, I use the class initialization section, in which I wrote the following code:
initialization
begin
Vcl.Graphics.TPicture.RegisterFileFormat('svg', 'Scalable Vector Graphics', TWSVGGraphic);
end;
However I found that, since the XE8 compiler version, the TImage constructor is called before my initialization section, causing thus apparently the above mentioned issue. All the compiler versions since XE8 are affected, but this bug never happened on XE7 or earlier. So something changed since XE8.
Here are my questions:
Is the way I use for register my custom graphic class correct?
If not, what is the correct way to do that?
As something seems different since XE8, what it the new correct manner to register my graphic component?
Did anyone else faced the same issue? How he resolved it?
Is this may be a new RAD Studio bug, or the issue is rather on my side?

This is most likely a side effect of the smart loading the IDE applies to design time packages. You can overwrite this behavior by calling ForceDemandLoadState(dlDisable) during the Register procedure of your package.
More about this can be found in the documentation of more recent versions of Delphi than XE8: Explicitly disabling smart loading of components in a design-time package

Related

Delphi - How to correctly register a custom graphic class since Rio 10.3.3

So I'm developing a graphic library providing a custom SVG image format which may be used within a TPicture, or any VCL component supporting a graphic image, like e.g a TImage. I wrote and maintain my library package since the XE7 compiler version, and my code is backward compatible until the XE2 version.
In order to declare my custom graphic format to the IDE, I call the following code from the initialization section of my graphic class
Vcl.Graphics.TPicture.RegisterFileFormat('svg', 'Scalable Vector Graphics', TWSVGGraphic);
However this seems to no longer works since the last RAD Studio 10.3.3 Rio version. I already faced a similar issue in the past, for which I could find a solution:
Delphi - How to correctly register a graphic class since XE8?
So, apparently Embarcadero changed the rules since the 10.3.3 Rio version. Once again. My graphic class is no longer registered correctly since this version. Sometimes it is, sometimes it isn't. For example, when I open my IDE for the first time, it isn't. When I try to debug my package in design time, it is. When I try to run a project, sometimes it is, sometimes it isn't.
Has someone faced a similar issue? Are the rules about the initialization section changed in the most recent compiler versions? Finally, what the hell is wrong with my code?
Or perhaps I still not understand how to correctly register a graphic class in Delphi, even after so many years. In this case, I would be very grateful if someone may explain me how to correctly register a graphic class, in order to never more facing a such issue in the future.

Using VCL Styles in a DLL causes System Exception in 10.2 Tokyo

An application originally written in XE2 that uses styles within DLL's so that forms that popup from DLL's are the same style as the EXE, when updated to build in 10.2 Tokyo, now causes System Exceptions when opening certain forms from the EXE, or when closing certain forms in the EXE.
I don't need to include the minimal reproducible example in this question, because I have an answer, that someone else may have been able to add to my original question had it not been closed so quickly, and then not re-opened even after making it on-topic.
Turns out it's a behavioural issue in VCL:
Exception if using comboboxes in a form that resides in a DLL and that uses VCLStyles.
Embarcadero won't fix it as it's not a "problem",
R&D writes that the style manager has to be enabled in the application
and there can be only one one TStyleManager with enabled system hooks
(TStyleManager.SystemHooks property), because it process all windows
from application. The current system doesn't support the scenario you
are suggesting, and there is currently no plan to rework it
but there is a workaround which is to add the following line of code immediately before calling SetStyle or TrySetStyle in the DLL code:
TStyleManager.SystemHooks := [];
Hopefully this will be of assistance to Delphi developers who run into this annoying problem after upgrading to the newer versions.
In my case, I add a conditional define to the project for the libraries, then add this code to the places where it setting styles, as the same unit is included in both EXE and DLL:
{$IFDEF DLL}
TStyleManager.SystemHooks := [];
{$ENDIF}

Adding an Unit or New Form in Delphi causes Access Violation

When I add a file or form to a Delphi project, often I get an access violation. Then I have to restart Delphi, open the project and try it again. Then it sometimes workes, sometimes I get the same Access violation. I am having this issue in all Delphi versions since XE8.
Other Delphi programmers seems to have the same problems, as here on the Community of Embarcadero: https://community.embarcadero.com/forum/programming/9387-creating-a-new-unit-or-new-form-in-delphi-10-2-3-causes-access-violation
Some people say that it's caused by third part libraries. I doubt that. When you look at the stacktrace, there is no third party library.
To reproduce:
Work in a (somewhat) larger project and make some code changes before adding a unit.
Add a new unit/form: File>New>Unit - or add an existing file using drag and drop or 'Add file to project' - Or delete a file from a project.
I contacted Embarcadero about this. They know about this issue and they replied as following:
It's due to some Castalia code, that's merged in Delphi since XE8. It's only possible to reduce this issue, so it will happen less often. Use: Tools - Options - Editor Options - Color - Structural Highlighting and switch everything off.
Looking at how the code is integrated into the IDE, this results in less editor parsing and repainting. Irrespective of that, the handler that causes the Access violation is still attached to the editor.
So basically, we will have to wait for this to be fixed in 10.3.
But a while later, I discovered, that the Access violation only occurs if you have closed the project's 'dpr file'. So as a work-around:
Don't close the dpr-file and you won't get the Access violation.

Loading a particular frame in Delphi 6 causes it to exit immediately

I have a frame that never had any problems before. Now when I am in the Delphi 6 IDE and I try to draw an instance of it on a Form in design mode, the IDE exits immediately without any crash errors, dialog boxes, or Watson style "please report this error" message boxes. I am running on Windows XP and I have never seen the Delphi IDE do this before. The frame doesn't even have any of my custom components on it, just some of the stock Delphi VCL components and a few third party components from a library that I have used without trouble for years. I tried several other frames resident in my project and I can still create those at design time without error.
Note, I did try a complete clean of all project DCUs and rebuilt several Delphi packages for my custom VCL components just in case but those efforts changed nothing.
Does anyone have any tips for diagnosing and fixing this problem?
It is possible to configure Delphi to debug itself. You launch a second copy of Delphi, and you might be able to see where in your code, and the only reasonable thing I can assume is that suddenly there is a problem with the code of the third party library components. To locate the source and line number of that crash, the Delphi debugger itself may be of some use.
Simply launch the third party component with Delphi.exe as the host executable (for Delphi 6 and 7), or bds.exe (for more recent Delphi versions). (In the IDE using Run Parameters, in the Host Application, put delphi.exe or bds.exe)
Then once you've located the source of the exception and fixed the code and recompiled the component packages containing that code, your problem may be solved.
Related answer by me
(Note that the madExcept idea is equivalent in that it might also give you a stack traceback to help you find what code is crashing, but in case it doesn't this technique is also valuable to know about.)

One project in Delphi 2007 doesn't show procedure name in the IDE Obj Inspector's Events

I have a Delphi project in 2007 that doesn't show the procedure names in the Object Inspector's Events such as Form OnClose, OnCreate or OnShow in the IDE. The code is there and if you click on OnCreate (for example) you are taken to the code and the IDE fills in the name of procedure. However on reload, the procedures are missing from the IDE again.
This same project causes various error messages when Delphi closes also, but I am not sure if this is related (no other project developed under this Delphi does but this one is the largest app and uses several 3rd party add-in libraries).
I have moved this app to various Delphi 2007 installations and it reacts the same, so it isn't a corrupt Delphi situation. Is there any way to rebuild or fix a corrupt project like this? Any help would be appreciated.
I would try to remove all the files and keep only the dpr and the pas/dfm files in case it's a corrupted project file.
I would also double check if there is any Form inheritance mess, as I have seen somewhat similar issues with the inherited event handlers. (look at the dfm files directly)
Try delete all the .DCU's, close Delphi, restart Delphi then rebuild your project.
Delphi's IDE takes several liberties with your code without warning you.
In particular : if you have a callback (eg: "TMyForm.FormCreate") linked in the dfm, and the IDE detects that the function's body is empty, when you save your unit, the ide removes the declaration and the implementation before saving your file.
Adding anything (even a simple "//") in the function's body prevents this : try typing some code or some comment in your function before closing your Delphi.
As for errors when Delphi closes, there can be so many reasons.
Do you have any third-party components or experts installed ?
Have you tried installing IDEFixpack for D2007 ?

Resources