- RAD Studio XE Tour - This week in Montreal, Portland, Calgary, Seattle, Sacramento
- Delphi XE Compatible Third Party Tools & Components
- RAD Studio XE Compatible Third Party Tools & Components
- RAD Studio XE Reviewer's Guide
- RAD Studio XE in the News - Delphi XE, C++Builder XE, Delphi Prism XE and RadPHP XE
- A Mandelbrot and Julia Set Implementation - Source Code Delphi Application
- Goodies and Bugs in Delphi XE
- Use Custom Check Box Images for a ListView - Delphi 's TListView Checkboxes are Ugly
- BlackFish SQL Gone in Delphi XE, What About a Replacement?
- Bug fix list for Delphi XE and C++Builder XE
- Delphi XE Released
- Embarcadero Accelerates the Development Process with New Releases of Delphi, C++Builder and RAD Studio
Andy’s Blog and Tools
How to tune Delphi XE’s start up
When I started Delphi XE today the first time, I recognized a 6 second delay when it shows “IDE Packages loaded” in the splash screen. On the second start it still shows “IDE Packages loaded” for 5 seconds. Because I wanted to know what the IDE does in those 5 seconds with 100% CPU load (25% on my 4 CPU machine), I debugged the IDE with an empty IDEFixPack for Delphi XE project (sorry no bug fixes yet ). I pressed the Pause-Button when it reached the delay.
The function that I saw in the call stack was the TStrings.IndexOfName method that was called by TStrings.SetValue. The string list contained about 3000 items. All of them were files in $(BDS)\source. That means that something enumerates all source file names and put them in the string list in the format “filename=path”. Returning from TStrings.SetValue showed me the IDE plugin that is responsible for the startup delay: Beyond Compare. The IDE plugin seems to cache file locations. I don’t know why it needs the location of all source files, but not on my computer. I have removed BC from the “Experts” registry key and now my IDE starts much faster.
BTW: Don’t forget to disable the Component-Toolbar package if you want to switch faster from Code to Design view.
Why components shouldn’t use named sync. objects
I promised my colleagues that with the switch to Delphi 2009 every thing becomes better. When I worked with Delphi 2009 at home I got the impression that it was usable for larger projects (our code doesn’t employ generics, it is plain Delphi 7 code). So this year I migrated one of our larger projects to Delphi 2009. The project’s code was migrated in less than half a day. Most work was to “fix” the new hints and warnings. And because we have the source code of all component packs I’ve spend two days fixing Unicode related bugs, rewriting assembler functions and adjusting the components to the 7 years younger RTL and VCL. (note to myself: we have way too many component packs).
After all the migration work was done, it became time to start the application the first time with Delphi 2009. It looked promising. Some visual glitches (black panels, missing checkbox captions due to wrong ParentBackground settings) but it looked good. Then I closed the application. And… Oh, Delphi 2009 didn’t responded anymore. Our application’s process was still alive. “A dead-lock in the debugger” was my first thought. I tried to start a second IDE instance to attach it to the first IDE to get some useful information from the call stack. But the second IDE never got past the splash screen. I stopped digging deeper at that point. I killed the IDE (what automatically killed our application’s process) and restarted it, opened the project and started it again with the intent to close it directly after the main form appeared. And… again a dead-lock in the IDE.
Last month I came up with the idea of calling Windows.TerminateProcess() in the main form’s OnClose event if a debugger is attached. That finally allowed us to debug the application without continuously restarting the IDE. But the IDE still ran into dead-locks when the application was running. I know that Delphi 2009 has some dead-lock problems but I never saw them in that extent.
Last week one of my colleagues told me that he doesn’t see the FastMM memory leak report anymore. To show me, he intentionally forced a memory leak in the application. No dialog, but FastMM was in debug-mode. After some minutes we remembered that I had put that TerminateProcess() into the OnClose event handler. After removing it we saw the FastMM memory leak dialog. So we had two possibilities, detect memory leaks and restart the IDE, or do not detect memory leaks but less IDE restarting (the IDE sometimes still ”dead-locked” when the application was debugged).
It was two days ago when I had to work on that migrated project myself. And guess what, I was more busy restarting Delphi 2009 than fixing a bug. I was already thinking about how I could have ever suggested to buy Delphi 2009. But that day was the day I finally found out where this dead-lock came from. With ProcessExplorer I could see that the IDE has a mutex named “H” that was hold by our application. I asked myself “How could that be?”. To dig deeper into this I started the kernel debugger “kd” the first time in my live. It showed my that the main thread of our application holds the mutex named “H” and that the IDE is waiting for the exact same mutex. But what creates that mutex? I ran a search for “CreateMutex” over our code, but found nothing (I didn’t think about “TMutex.Create” at that moment). What else could it be? Maybe TortoiseSVN’s DLL hook? I gave the “CreateMutex” a last shot. I ran the search over our components directory. I found some calls to “CreateMutex” but none used the name “H”. “Unless it is ‘HookAPI:{….}’”, I thought. “Wait, that is from those very old component pack that I had unicodified myself” (who’s name I will not tell). I looked at the unit that contained the CreateMutex call and saw more BASM code than Pascal code. Even the CreateMutexA function was imported via GetProcAddress. Have you noticed the “A” in “CreateMutexA”. With the switch to Unicode the “HookAPI:{…}” string became unicode but the assembler code called the ANSI version of CreateMutex.
That means that the “H” mutex is the “HookAPI:{…}” mutex. It is used to protect some scrollbar hooks. I should have mentioned that WinDbg showed me that the IDE was waiting in the FlatSB_SetScrollInfo API. Unfortunately I couldn’t attach WinDbg to the project’s process because it was already debugged by the IDE. So this all finally made sense. Every time the application was paused or closed the IDE wanted to update some scrollbars but if the project was doing the same thing before it was paused, we got a dead-lock.
I decided to disable the whole scrollbar hooking code of that component pack because with the introduction of XP Theming this code became obsolete years ago, but nobody noticed this (how often do you look at component code that you’ve used for years).
My advice to component vendors:
If you use named synchronization objects, please write your code in a way that those objects aren’t used in the IDE or attach the process ID to the name.
Delphi 2010 component toolbar slows down the IDE
If you use Delphi 2010, you have many components installed and you don’t use the “old” component toolbar that was brought back in Delphi 2010 you may want to remove the comptoolbar140.bpl from the “Known IDE Packages” registry key. Without it switching between Code and Design view becomes a lot faster. Hiding it doesn’t help, you have to remove the package from the registry.
Delphi 2009/2010 Post-Build events
Have you ever wondered if it is possible to execute the “Post-Build events” only when the project was actually updated/compiled? With Delphi 2009/2010 you can do that easily by changing the “Execute when” combobox in the “Post-Build events” edit dialog to “Target is out-of-date”. At least you thought that would do the trick. Instead it disables the Post-Build event what means that it is never executed.
I did some research on this because I needed this functionality. Without it the “Execute when” = “Always” setting tells msbuild to execute the post-build script even if the compiler didn’t do anything. And that causes msbuild to build targets that don’t need to be built.
But what is the problem with “Target is out-of-date”. Let’s have a look into the msbuild script that executes the Post-Build events. The “PostBuildEvent” target in $(BDS)\bin\CodeGear.Common.Targets is declared as:
Now let’s see what msbuild with “/v:diag” tells us about this target.
'$(RunPostBuildEvent)'=='Always' or '$(RunPostBuildEvent)'=='' or '$(PreOutputTimeStamp)'!='$(PostOutputTimeStamp)'is evaluated to
'OutOfDate'=='Always' or 'OutOfDate'=='' or ''!=''The first two conditions are ok and mean that we have to look at the third condition for our out-of-date check. But what is with the third condition? Why is it an empty string comparison that is always false? And where do PreOutputTimeStamp and PostOutputTimeStamp come from? They are declared some lines about the “PostBuildEvent” target.
<Target Name="_PreOutputTimeStamp"> <CreateItem Include="%(OutputFile.ModifiedTime)"> <Output TaskParameter="Include" PropertyName="PreOutputTimeStamp"/> </CreateItem> </Target> <Target Name="_PostOutputTimeStamp"> <CreateItem Include="%(OutputFile.ModifiedTime)"> <Output TaskParameter="Include" PropertyName="PostOutputTimeStamp"/> </CreateItem> </Target>So the PreOutputTimeStamp is the modified time of the output file (EXE/DLL/BPL) before it was compiled and the PostOutputTimeStamp is the modified time of the same file after msbuild has done its work. But why are they empty?
The item “OutputFile” is not declared or set anywhere. Neither in CodeGear.Common.Targets nor in CodeGear.Delphi.Targets nor in MyProject.dproj. And that is why both msbuild properties are evaluated to empty strings.
With this knowledge I was now able to fix the this bug by adding the missing “OutputFile” item to the CodeGear.Delphi.Targets file.
<ItemGroup> <_MSBuildProjectFullPath Include="$(MSBuildProjectFullPath)"/> <_DependencyCheckOutputName Include="$(DCC_DependencyCheckOutputName)"/> + <OutputFile Include="$(DCC_DependencyCheckOutputName)"/> </ItemGroup>After this change the “Target is out-of-date” combobox item in the “Post-Build events” dialog started to work as expected.
One issue solved. But that wasn’t all that I needed for my build script. In order to reduce the file size of our massive EXE files we strip the PE format’s relocation section from the EXEs and we create and attach *.jdbg files to our EXEs. But both post-build events aren’t necessary when we debug our projects in the IDE, especially not the relocation section removal. In the IDE we want a fast edit-compile-debug turn-around. So I had to find a way to only execute those post-build events when the Release-Configuration was active.
Unfortunately Delphi doesn’t support this feature. But after browsing through the CodeGear.*.Targets files and reading msbuild /v:diag log files, I had the solution right there sitting in front of me. The $(OUTPUTPATH) from the post-build events are replaced by msbuild properties when msbuild processes the build script. So I had the idea of just trying to use other properties from msbuild in addition to the macros that are listed in the Post-Build events edit dialog. And with $(Config) I had the active configuration right at hand.
And with the active configuration being set to “Debug”, msbuild executes this as:
if "Debug" == "Release" ( stripreloc.exe ... linkmapfile.exe ... )Now that I have solved the build script issues, I can turn to all the other “things” that I have to solve, think about and develop before all my co-workers can start working with the new Delphi IDE.
Those “things” are things like keeping the components as part of the project to make it possible to update to a new component version without breaking older project versions. And I’m not speaking of using the “-r” IDE command line option. That’s what we used in the older Delphi version. I’m speaking of opening a project from the 1.0 branch, closing it and opening the same project from the 7.0 branch that requires newer versions of the components. Furthermore the components are in the project’s svn folder, so they have the same revision number. (Our old svn “layout” was to have a separate svn repository for the components) And if you svn-update and somebody has changed the components, the IDE automatically compiles them and loads them when you open the project. And today this IDE plugin passed it’s final tests.
JVCL TJvTransparentForm rewritten
Yesterday our product manager came to me and asked me to replace our old splash screen with a new more fancy one that he had designed. The new splash image has alpha transparency and so we had to make our splash form a layered window. Unfortunately the UpdateLayeredWindow() API function doesn’t allow to use controls on the form. After half an hour I came up with a solution that I found on the Internet and as a result I decided to rewrite the JEDI JVCL component TJvTransparentForm to not only support regions but also layered windows. Now it is just loading a PNG image into a TImage control and placing a TJvTransparentForm on the splash form to get everything done.
Semi-Transparent form in action
In design mode
The smiley in the picture is not our new splash image.


