IDE fix pack 4.2 released

Andreas Hausladen has released another version of his IDE fix pack.

These are the changes:

  • Added: Prevent IDE deadlocks
  • Added: HelpInsight parsering is done in the background when moving the mouse over an identifier
  • Added: Much improved IDE startup performance
  • Added: Some old Debugger C-RTL functions are replaced by much faster versions

Click here to download the actual version.

Continuous Integration with Hudson, Subversion and Delphi

Recently I have read an article about continuous integration with Hudson in “entwickler magazin” 1.2011. But this article was about Hudson and PHP only.

I was wondering, if there is any possibility to use Hudson for my Delphi projects. Indeed, the Delphi developers themselves are actually using this build system.

Here are some links:

I had put off the implementation of an automatic build system a long time. Now, I decided to implement such a system in my days off between christmas and the new year.

Here is a small how to:

1. VMWare Setup

Create a virtual machine. My favorite is VMWare Workstation.

For optimum performance you should set the disk capacity of the virtual disk to a fixed value.

If you want save backups of this vm under FAT32 systems, you should split the virtual disk into pieces of  2  GB.

In my case I am using Windows XP with 50 GB fixed disk space in one single file.

    set virtual machine name and location

    set size and vm splitting

    set up hardware settings with button "Customize hardware"

    set the memory to 1024 MB, set the amount of CPUs and remove the floppy disk drive

2. Windows Installation and updates

Install operating system

Windows installation

After installing OS I do always a snapshot of the actual virtual machine  state. With this snapshot you can revert to a clean operating system in case of problems.
Install VMWare tools
Install all service packs and updates of the used operating system
Activate operating system

3. Software installation

4. Delphi

You can install a run a full Delphi installation.

Or you can copy some files from your original system to the build system:

Original “C:\Program Files (x86)\Embarcadero\RAD Studio\7.0\bin” –> to build vm “C:\Continuous Integration\Delphi\bin”

Original “C:\Program Files (x86)\Embarcadero\RAD Studio\7.0\lib” –> to build vm “C:\Continuous Integration\Delphi\lib”

Original “C:\Program Files (x86)\Embarcadero\RAD Studio\7.0\Imports” –> to build vm “C:\Continuous Integration\Delphi\Imports”

5. Hudson first start

Hint: you must have installed Java.

Create a batch file named “start hudson.cmd” with the following content:

Start Hudson batch file

Run this batch file.

The other way is to run this command from the command line.

Open the following url in your web browser: http://localhost:8080/ and you can see the Hudson dashboard:

Hudson first start

6. Hudson setup

Name of Hudson

First we want to change the name of Hudson – therefore  click “Manage Hudson” and than click on “Configure System”. In the bottom change the “Hudson url” from http://localhost:8080/ to http://whatyouwant:8080/ and save the changes.

Install Hudson as a service

Hint: you must have installed .NET 2.0 for the Windows service installation.

In the Dashboard, click “Manage Hudson” and than click “Install as Windows Service”.

Than you have to specify the installation directory:

install hudson as a windows service

In my case I changed the installation directory to “C:\Continuous Integration\Hudson”.

Click “install” button, wait until the service is installed and than restart Hudson.

Set up e-mail

In the Dashboard, click “Manage Hudson” and than click “Configure System”.

In the area “E-mail Notification” specify your smtp server, the admins e-mail address and if neccessary click on “Advanced” and set up your SMTP Authentification.

Click “Save”.

Create the first job

In the Dashboard click “New Job”.

Specifiy a job name.

Select “Build a free-style software project”.

Click “OK”.

In “Advanced Project Options” you can specifiy a custom workspace. I suggest to use a custom workspace. Don’t doing so, Hudson will create a full copy of your subversion folder in every workspace of each job. Imagine you have many jobs and more than 1 Gigabyte of source code…

My custom workspace is “C:\Continuous Integration\SVN”.

In the “Source Code Management” area we have to select “Subversion”. Specify your “Repository URL” and type in credential if neccessary.

Check “Use update”

Check “Revert”

In area “Build Triggers” check “Poll SCM” and type in

0,5,10,15,20,25,30,35,40,45,50,55 * * * *

to poll the source code management system every 5 minutes.

In area “Build” add a build step. For instance “Execute a Windows batch command and type in “echo test”.

In area “Post-build Actions” check “E-mail Notification”, type in minimum one e-mail address in field “Recipients” and check “Send e-mail for every unstable build”.

Click “Save”.

Run the first job

Click “Build now” to start the first job.

You can see a progressbar on the left side. Click on that progressbar to get detailed information about the actual build state. If everything is fine, Hudson does a SVN update into “C:\Continuous Integration\SVN”.

Waint until the build is finished.

Build Delphi components
You have to configure the job. Go to “Execute Windows batch command”.
In Delphi projects you have to build Delphi components and then your Delphi projects.
So we build the components first.
In my example there is a group project file with all third party components.

@ECHO OFF
echo Delete old share, create a new one, map the share to K:\
NET SHARE "Delphi components" /DELETE
net share "Delphi components"="C:\Continuous Integration\SVN\Delphi components"
net use K: /delete /yes > NUL
START /wait net use K: "\\sfci\Delphi components" /PERSISTENT:NO
echo set up environment variables
SET BDS=C:\Continuous Integration\Delphi
SET Win32LibraryPath=%BDS%\lib;%BDS%\Imports;%BDS%\Lib\Indy10;%BDS%\include;%BDS%\RaveReports\Lib;K:\_Output\DCP;K:\VirtualTrees\VirtualTrees V.4.8.6\Source;
SET APPDATA=C:\Dokumente und Einstellungen\ci\Anwendungsdaten
echo building components
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild.exe /nologo /t:Build /p:config=Release /verbosity:quiet "K:\AllMyComponents_Delphi_2010.groupproj" /p:Win32DCPOutput=K:\_Output\DCP /p:Win32DLLOutputPath=K:\_Output\BPL

Save again und try to build the  job.

In Win32LibraryPath you have to specifiy all paths that are in your library path in your Delphi IDE.

Build Delphi projects

Now you can add a second  ”Execute Windows batch command” where you build your Delphi project.

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild.exe /nologo /t:Build /p:config=Release /verbosity:quiet "C:\Continuous Integration\SVN\AllMyDelphiProjects.groupproj"

Run Inno Setup

After building your Software you can run a setup creation tool of your choice.
Here is an example of calling Inno Setup from command line:

iscc “c:\isetup\samples\my script.iss”
You can add another  ”Execute Windows batch command” for that.

Delphi IDE: Breakpoints / Haltepunkte sind defekt

Vielleicht ist es euch auch schon mal passiert: die möglichen Haltepunkte in einer Unit sind nicht dort platziert wo sie es eigentlich sollten. Damit ist das Debuggen eigentlich so gut wie unmöglich.

Das Problem ist möglicherweise, dass irgendwo ein Zeilenende einer Zeile nicht gesetzt ist.

Abhilfe schafft hier folgende Lösung: man lade die betroffene Unit in einen Texteditor, welcher Zeilenenden konvertieren kann. Meine Empfehlung hier ist Notepad++.
Einmal alle Zeilenenden nach Unix und dann wieder zurück nach Windows konvertiert und schon kann das Debugging wie gewünscht weitergehen.

Ich benötige dringend den Zugriff auf eine protected Methode…

… eines Komponentenherstellers und man möchte ungern den Originalquellcode anpassen.

Man kann sich hier mittels eines kleinen Hacks bedienen.

Originalcode:

type
TOriginalClass = class(TObject)
protected
function ProtectedFunction(const AValue: string): Boolean;
end;

Eigene Klasse

type
TMyClassHack = class(TOriginalClass)
public
function ProtectedFunction(const AValue: string): Boolean; override;
end;

Verwendung:

begin
...
TMyClassHack(MyOriginalClassObject).ProtectedFunction(AValue);
...

Delphi Shortcuts

STRG+CTRL+G –> erzeugt eine GUID (Global Unique Identifier)
STRG+K+O –> markierter Text wird klein geschrieben
STRG+K+N –> markierter Text wird groß geschrieben
STRG+CTRL+i –> der Text der ausgewählten Zeilen wird nach rechts verschoben
STRG+CTRL+u –> der Text der ausgewählten Zeilen wird nach links verschoben

Ribbon Recent items

Die Umsetzung des Ribbon Controls seitens Embarcadero lässt an einigen Stellen sehr zu wünschen übrig. Nachdem ich heute den Grund des häufigen Flickerns ausfindig machen und beheben konnte, ergab sich ein Problem mit der länge der Recent Items im ApplicationMenu.

Dort kann man zwar problemlos RecentItems hinzufügen per

Ribbon1.AddRecentItem(AFileName);

Hat man nun aber sehr lange Dateinamen, dann sieht der Anwender lediglich den Pfadnamen und der Dateiname wird abgeschnitten. Das ist nicht wirklich im Sinne des Erfinders.

In der Unit Ribbon.pas im Verzeichnis C:\Program Files (x86)\Embarcadero\RAD Studio\7.0\source\Win32\vcl

habe ich folgendes Änderungen vorgenommen:


procedure TCustomRibbon.RecentActionHandler(Sender: TObject);
begin
// emba code
// DoRecentItemClick(TAction(Sender).Caption, TAction(Sender).Tag);
// new code:
DoRecentItemClick(TAction(Sender).Hint, TAction(Sender).Tag);
end;

und in der function AddRecentItem(…)

folgende Änderung:

// fix by HAM 2010-10-19:
// LAction.Caption := FileName;
LAction.Caption := ExtractFileName(FileName);
LAction.Hint := FileName;
LItem.Hint := FileName;
// end of fix

Damit wird der Pfad immerhin noch im Hint des TAction Items zwischengespeichert und angezeigt wird der kurze per ExtractFileName() extrahierte Dateiname.

Im RecentActionClick event wird dann auf der voll Dateiname übergeben.

Delete folders recursively

Here is an example batch file that deletes all Delphi “__history” folders recursively:

BOF of batch file:
===========

@ECHO OFF
ECHO.

@SET DELPHI_PROJECTDIR=C:\DELPHI_PROJECTS

REM delete all __history folders recursively
FOR /D /R "%DELPHI_PROJECTDIR%" %%d IN (__history) DO (
  IF EXIST "%%d" (
    echo deleting temp directory "%%d"
    RMDIR /S /Q "%%d"
  )
)
PAUSE

===========
EOF of batch file