I can't see any noticeable delay in Delphi 11 startup caused by GExperts on my computer. It takes about 10 seconds regardless whether GExperts is active or not.
Are we talking about the release build of GExperts? The one you get by running the build script GExperts\Projects\DelphiXx11Alexandria_Build_Project.cmd ?
If you build the DLL from within the IDE it is compiled in debug mode by default which writes all sorts of debug information. Maybe that's what you are experiencing.
Last edit: Thomas Mueller 2022-07-30
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
my colleague and I are experiencing the same proplem . We were using the GXRS11_1.3.21_experimental-twm_2022-04-09_Beta.exe. Yesterday I downloaded the source code and built the DLL using the script first, whith the same result as before. Then I built it in the IDE after changing to Release, again with the same result.
It happens reliably on both our office and home office computers, usually at the first start every day (the office computers run 24/7) and after a reboot. If you start Delphi several times without a reboot in between, it starts quickly, otherwise it can take three minutes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I can confirm this problem. From my observation it only happens if Windows uses display scaling (125% = 120 dpi in my case), and on the first start of the Delphi IDE. And it happens while installing the "Favorite Files Expert". I've placed some code to measure the execution time while installing all GExperts, and TfmFavFiles.Create() takes up to ~100 seconds (sometimes even more).
The delay is caused by TfmFavFiles.ApplyDpi() -> ResizeImagesForHighDPI (with dpi=120) containing 755 images.
I've attached a log file from my "Stopwatch" measure; showing the execution time while installing the experts. Hopefully Thomas can uses this log to find the real cause of the problem.
Could you please provide me with your timing code? I could probably write some myself, but why should I if it already exists?
I have done some refactoring of TImageListScaler.ResizeImagesforHighDPI in revision #3878 but I am afraid it won't make much of a difference.
I could try to move some of this code to a background thread but I am always very hesitant to do that with an VCL related code as it usually creates more problems than it is worth.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Please, note: You're defining a compiler switch IDE_IS_HIDPI_AWARE. Unfortunately, this doesn't take into consideration yet, that Delphi 11.2 can be startet with or without DPI awareness (the latter by using the parameter /highdpi:unaware). It also provides a suitable start menu entry.
As long as people compile their own DLL it might not matter, but I think a more reliable approach would be to determine DPI awareness at runtime.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That doesn't matter. If the IDE is started with /highdpi:unaware Windows will report 96 DPI anyway and everything works like it did with older Delphi versions.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've used DbgView and ProcMon from SysInternals to find the bottleneck...
Workaround:
If you don't use the Favorite Files Expert; disable it in the GExperts configuration and restart the Delphi IDE. This is also helpful when debugging a 2nd instance of the IDE (where you keep FavFiles enabled).
Cause:
The huge delay is caused by scaling the two SystemImageLists "ilSystem" and "ilSysLarge" created in TfmFavFiles.SetupSystemImageLists to the current DPI value. In my case, both lists contain over 800 images (file types and application icons).
In ResizeImagesforHighDPI() each image and corresponding mask is fetched from the SystemImageList using ImageList_DrawEx(). But that Windows API function tries to find the requested image by scanning the IconCache and installed applications. It even scans my network drives for the application executable! I've used ProcMon to see that Windows is scanning my whole local harddisk and network drives for Inkscape.exe while trying to load the icon for SVG files... That consumes a lot of time while blocking the application.
However: The current code causes unneccesary scaling: If the IDE runs in HighDPI-Mode on a scaled Windows (say: 125% = 120 dpi), in TfmFavFiles.SetupSystemImageLists the calls to SHGetFileInfo() already retrieves the ImageList with 20px (SHGFI_SMALLICON) or 40px (SHGFI_ICON). But since TImageList has no property to fetch the original dpi information, the code in TImageListScaler.ResizeImagesforHighDPI() assumes the original ImageList is for 96 dpi.
I've created a patch which will use TImageList.Tag for storing the DPI information. In combination with some changes to u_dzDpiScaleUtils this works OK now (for me).
I have just committed Achim's patch to revision #3885. Could everybody affected please compile a new dll with these changes and report whether this fixes the problem?
And of course: Thanks a lot, Achim, for taking the time and effort tracking down the reason for this delay. I am sure I wouldn't have found this myself.
Last edit: Thomas Mueller 2022-09-23
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried it and the loading stops for about 10s instead 3min.
Thank you :)
Since Delphi 10.3 there's a TVirtualImageList, which takes care of the scaling itself. It gets fed by a TVirtualImageCollection and might be worth a look in respect of future releases.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I just looked into this and I think it's more trouble than it's worth. If somebody else wants to invest the time and effort, I'll accept patches. But please keep in mind that GExperts supports all Delphi versions back to Delphi 6 so a solution that only works for Delphi 10.3 and later is not acceptable.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I can't see any noticeable delay in Delphi 11 startup caused by GExperts on my computer. It takes about 10 seconds regardless whether GExperts is active or not.
Are we talking about the release build of GExperts? The one you get by running the build script GExperts\Projects\DelphiXx11Alexandria_Build_Project.cmd ?
If you build the DLL from within the IDE it is compiled in debug mode by default which writes all sorts of debug information. Maybe that's what you are experiencing.
Last edit: Thomas Mueller 2022-07-30
I use the script for compilation.
Hi,
my colleague and I are experiencing the same proplem . We were using the GXRS11_1.3.21_experimental-twm_2022-04-09_Beta.exe. Yesterday I downloaded the source code and built the DLL using the script first, whith the same result as before. Then I built it in the IDE after changing to Release, again with the same result.
It happens reliably on both our office and home office computers, usually at the first start every day (the office computers run 24/7) and after a reboot. If you start Delphi several times without a reboot in between, it starts quickly, otherwise it can take three minutes.
I can confirm this problem. From my observation it only happens if Windows uses display scaling (125% = 120 dpi in my case), and on the first start of the Delphi IDE. And it happens while installing the "Favorite Files Expert". I've placed some code to measure the execution time while installing all GExperts, and TfmFavFiles.Create() takes up to ~100 seconds (sometimes even more).
The delay is caused by TfmFavFiles.ApplyDpi() -> ResizeImagesForHighDPI (with dpi=120) containing 755 images.
I've attached a log file from my "Stopwatch" measure; showing the execution time while installing the experts. Hopefully Thomas can uses this log to find the real cause of the problem.
Could you please provide me with your timing code? I could probably write some myself, but why should I if it already exists?
I have done some refactoring of TImageListScaler.ResizeImagesforHighDPI in revision #3878 but I am afraid it won't make much of a difference.
I could try to move some of this code to a background thread but I am always very hesitant to do that with an VCL related code as it usually creates more problems than it is worth.
Please, note: You're defining a compiler switch IDE_IS_HIDPI_AWARE. Unfortunately, this doesn't take into consideration yet, that Delphi 11.2 can be startet with or without DPI awareness (the latter by using the parameter /highdpi:unaware). It also provides a suitable start menu entry.
As long as people compile their own DLL it might not matter, but I think a more reliable approach would be to determine DPI awareness at runtime.
That doesn't matter. If the IDE is started with /highdpi:unaware Windows will report 96 DPI anyway and everything works like it did with older Delphi versions.
Sorry for the late reply. I can't provide timing measure code because I reverted my changes while updating to rev. 3878. It was as simple as
I've used DbgView and ProcMon from SysInternals to find the bottleneck...
Workaround:
If you don't use the Favorite Files Expert; disable it in the GExperts configuration and restart the Delphi IDE. This is also helpful when debugging a 2nd instance of the IDE (where you keep FavFiles enabled).
Cause:
The huge delay is caused by scaling the two SystemImageLists "ilSystem" and "ilSysLarge" created in TfmFavFiles.SetupSystemImageLists to the current DPI value. In my case, both lists contain over 800 images (file types and application icons).
In ResizeImagesforHighDPI() each image and corresponding mask is fetched from the SystemImageList using ImageList_DrawEx(). But that Windows API function tries to find the requested image by scanning the IconCache and installed applications. It even scans my network drives for the application executable! I've used ProcMon to see that Windows is scanning my whole local harddisk and network drives for Inkscape.exe while trying to load the icon for SVG files... That consumes a lot of time while blocking the application.
Solution:
There is an option flag ILD_ASYNC to ImageList_DrawEx which could speed up things:
https://docs.microsoft.com/en-us/windows/win32/controls/imagelistdrawflags
"ILD_ASYNC Draw the image if it is available in the cache. Do not extract it automatically.[...]", but I did not try it yet.
However: The current code causes unneccesary scaling: If the IDE runs in HighDPI-Mode on a scaled Windows (say: 125% = 120 dpi), in TfmFavFiles.SetupSystemImageLists the calls to SHGetFileInfo() already retrieves the ImageList with 20px (SHGFI_SMALLICON) or 40px (SHGFI_ICON). But since TImageList has no property to fetch the original dpi information, the code in TImageListScaler.ResizeImagesforHighDPI() assumes the original ImageList is for 96 dpi.
I've created a patch which will use TImageList.Tag for storing the DPI information. In combination with some changes to u_dzDpiScaleUtils this works OK now (for me).
Last edit: Achim Kalwa 2022-09-13
Thank you Achim for the details.
Thomas, I can confirm that my delay is available at 11.2 also and I am running at 125% dpi = 120.
Thank you from us, too. In our case it's 175% (DPI = 168) on 4K monitors. My guess is, it will be the case whenever DPI > 96.
Last edit: pfennig59 2022-09-09
I have just committed Achim's patch to revision #3885. Could everybody affected please compile a new dll with these changes and report whether this fixes the problem?
And of course: Thanks a lot, Achim, for taking the time and effort tracking down the reason for this delay. I am sure I wouldn't have found this myself.
Last edit: Thomas Mueller 2022-09-23
I tried it and the loading stops for about 10s instead 3min.
Thank you :)
Since Delphi 10.3 there's a TVirtualImageList, which takes care of the scaling itself. It gets fed by a TVirtualImageCollection and might be worth a look in respect of future releases.
I just looked into this and I think it's more trouble than it's worth. If somebody else wants to invest the time and effort, I'll accept patches. But please keep in mind that GExperts supports all Delphi versions back to Delphi 6 so a solution that only works for Delphi 10.3 and later is not acceptable.