pointers, sizes

Just a small remember for myself:

If

TMyRecord = record
  pointer1: pointer;
  pointer2: pointer;
  pointer3: pointer;
  pointer4: pointer
end;
PMyRecord = ^TMyRecord;

then

  sizeof(TMyRecord) <> sizeof(PMyRecord)

So

  var rec: PMyRecord;

  rec = AllocMem(sizeof(rec));

is probably not a sensible thing to do (at least not if you intend to actually put something into that space the pointer points to).

At least it began breaking very, very soonish and consistently once TMyRecord got enough members – too bad though that I first looked at the completely wrong space.

Nothing beats the joy of seeing a very non-localized access violation go away after two hours of debugging though.

Reporting Engines

There are quite many solutions available to you if you want to create printed (or PDFed) reports from your delphi application, but surprisingly, one one is really convincing.

The so called professional solutions like Crystal Reports or List&Label are very expensive, require a large runtime to be deployed and may even require you as the developer to pay royalties per delivered client

So for my particular problem, the only solution was to use a VCL based engine that can be compiled into the exe and does not need any additional components to be deployed.

Years ago, I was told to use ReportBuilder and maybe people were even right there: Quick Reports (as in included into delphi back then) had and still has a very bad reputation, and RB was the only other VCL based product available

RB has some problems though. Lacking Delphi 2006 support, limited report templates, field formating on the database access layer and last but not least: A nasty bug preventing barcodes from being correctly rendered to PDF-Files.

Then, I had a look at Fast Report and I tell you: That piece of software is perfect!

Granted, switching will come with a bit of work, though the paradigms of both engines kinda match. But once you’ve done the stupid rebuilding of the old templates, you’ll notice how wonderful Fast Report actually is. And you will notice immediately as it’s very, very intuitive to use – compared to RB. Things that required custom programming or even a little hacking here and ther in RB just work in FR. And they even work without forcing you to read through lots of documentation in advance

And everything – just everything is in the report template. Number formats, even small scripts for changing the report in subtle ways while it’s being printed. Just perfect for what I was doing.

So, if you are looking for a nice, powerful really easy to use reporting enginet that can be fully compiled into your EXE, you should really go with FR. It even costs less than RB.

The myth of XCOPY deployment

Since the advent of .NET, everyone is talking about XCOPY deployment.

XCOPY deployment means that the applications are distributabe without a setup routine. Just copy the file(s) where you want them and that’s it.

We are being told that this is much easier and safer than the previous non-.NET approaches which – as they continue – always required a setup program.

The problem with those statements is that they are all false.

First the ease of use: Think of it: Say you want to install Cropper (which made me write this entry. I found that screenshot utility via flow|state). What you are getting is a ZIP-File, containing 5 files and a folder (containing another 6 files). Nearly all the files are needed for the application to run.

XCOPY deployment in this case means: Create a folder somewhere (Windows guidelines advocate you create that in c:Program Files which is a folder windows does not want you to mess with and per default does not display its contents) and copy over all those files, being aware not to forget a file or the folder in the archive.

But it does not end there: As you have to launch the application and going all the way through those folders, you will want to have a shortcut in the start menu or on the desktop. With this new and “better” method of deployment, you’ll have to do that yourself.

This is a tedious task involving lots of clicks and browsing. An unexperienced user may not be able to do this at all.

What an unexperienced user will want to do is to copy that application right to the desktop. But in this case this does not work well as the whole application consits of multiple interdependant parts. Copying only the .EXE will break the thing.

Compare this with Mac OS X

In Mac OS X, application also consist of multiple parts. But the shell is built with XCOPY deployment (not called like this, of course. As a matter of fact, it does not have a name at all) in mind: In OS X, you can create a special kind of folder which is a folder only on the file system. The shell displays it to the user as a single file – the application.

Whenever you move that “file” around, OS X will move the whole folder. When you double click the “file”, the application will launch (the binary is a file somewhere in this special folder. The shell is intelligent enough to find and launch that). When you delete it, the shell will delete the folder including it’s contents (of course).

This makes XCOPY deployment possible as the applications become one piece. You want it on the desktop? Drag it there. In the Application folder (without warnings about not being allowed to mess with its contents, btw)? Drag it there? On an USB-Stick? Drag it there.

Well. There’s one other thing: It’s the users data and the applications data. Most of the applications will be used to create data with them. And all application somehow create their own data (for saving things like the window state or position for example). As all modern OSes are multiuser ones where a user does not necessarily have to have write access everywhere, there’s the concept of the home directory. That one is yours. You may store whatever you want in there.

So naturally, this is the place where the applications should store data to0.

User data goes to a specific folder of the users choice. Per default, applications should suggest some Documents-Folder. Like “My Documents” in Windows or “Documents” in Mac OS. In most of the cases you don’t want to delete that on uninstall.

Application settings are in Windows stored in the Registry (under HKEY_CURRENT_USER – a hive that belongs to the current user like his home folder does. And actually, the file behind that is stored in the home folder aswell (USER.DAT)) or in the Application Data folder below the users home folder.

Mac OS X Applications are advised to use the Preferences-Folder inside the Library Folder inside the users home directory<./p>

Now. Application data is something you want to remove when you uninstall the application (which means deleting a bunch of files in Windows or one “File” in Mac OS). Application data is created by the application, for the application. No need to keep that.

In Mac OS, you can do that by going into the folder I’ve described above and delete the files – mostly named after your application. There are no warnings, no questions, no nothing. Just delete.

In Windows, editing the registry is off-limits for end-users and very, very tedious to do for experienced users (due to the suboptimal interface of regedit and because the whole thing is just too large to navigate it easily), so you generally let the stuff stick there. Deleting the Application Data in the same-named folder is also impossible for the end user: That folder is hidden by default. Explorer does not display it. And it’s hard as hell to find, as you have to manually navigate into your home directory – there’s not easy GUI-access to that. So that sticks too.

All in all, this means that windows is – at least in its current state – very unsuited for XCOPY deployment:

  • It does not help at keeping together things that must be together
  • Its complex file system structure makes it hard to copy the application where windows wants it to be
  • Manually creating shortcuts is not feasible for an unexperienced user
  • Uninstallation of Application Data is impossible

So, we found out that XCOPY deployment is not easy at all. Now let’s find out how it’s not true that only .NET enabled you to do this.

Ever since there is Delphi, there theoretically is XCOPY deployment.

Delphi is very good at creating self-contained executables.

With delphi it’s a breeze to create one single .EXE containing all the functionality you need. That one single .EXE can be moved around as a whole (obviously), can be deleted, can even be put right into the start menu (if you want that). It can even create the start menu shourcuts, delete application data – basically configure and clean itself

It can even uninstall itself (embed an uninstaller, launch that with CreateProcess and set the flag to delete the .exe after it ran). And it can contain all it’s image and video and sound data it needs.

Just because nobody did it does not mean it was not possible.

Face it: Windows users are used to fancy installers. Windows users are not at all used to dragging and dropping an application somewhere. And currently Windows users are not even able to do so as dragging and dropping will break the application.

OS X and now Linux allow for true XCOPY deployment of desktop applications.

Well, you say… then maybe XCOPY deployment is just for those fancy ASP.NET web applications?

Maybe. But after XCOPY you need to configure your webserver – at least create a virtual directory or host. A good installer could do that for you – if you want it to.

Microsoft too has seen that this XCOPY thingie is not as great as everyone expected, so they added the new “One-Click Install” technology, which is not much more than a brushed-up MSI file which does a old-fashioned install.

To really make XCOPY deployment a reality (btw, I’m a big fan of depolying software like this), there must be some changes within Windows itself. Microsoft, copy that application bundle feature from OSX. That one works really, really good.

Btw: Am I the only one that thinks “XCOPY deployment” is a very bad term? What is XCOPY? Who the hell still uses XCOPY these days? And when we are using the command line: COPY would be enough.

No topic-based help system installed

Recently I had to do some Delphi-work again. To my surprise, the online help seemed to have stopped working. I always got this error message:

No topic-based help system installed

Programming without an online help is very tedious and sometimes nearly impossible.

When I had to look up in which Unit TWinControl is declared, I had two possibilities: Either look it up in the source code (Borland ships the full source code to their class library) or fix the help system once and for all.

I deceided to do the latter (searching after TWinControl is no fun).

Googling in the web turned out nothing. In Groups most of the time, the suggestion was to reinstall the whole thing

I absolutely did not have time for this, so I dug deeper.

The problem is caused by the installation of the VS2005 Beta which resets some AppID-GUUID. Afterwards delphi crashes while loading the IDE-package htmlhelp290 which in the end causes delphi to think that there’s no help installed

I fixed it doing the following:

  1. Reset the help-viewer-appid. In the registry under HKEY_CLASSES_ROOTAppIDDExplore.exe, set AppId to {4A79114D-19E4-11d3-B86B-00C04F79F802}
  2. In HKEY_CURRENT_USERSoftwareBorlandBDS3.0Disabled IDE Packages remove the entry for htmlhelp290 that has been created.
  3. Start Delphi and use the help again

What I don’t know is if this has a negative effect to VS, but this does not matter for me: I need Delphi to work.

The whole thing is a consequence of the .NET orientation of delphi: Earlier, Delphi was as self-contained as the executables it can build: Drop it into a directory and run it. No problems, no questions asked.

With Delphi integrated into .NET and using .NET-Components, problems begin to rise: First there was a bug in D8 causing it to stop working after .NET 1.1 SP1, now this.

Hopefully, they find a way back to both .NET (for the acceptance in the buzzword-centered world where you can’t have a dev-tool not .NET capable) and self-containment.

Productive with Delphi 2005

Yesterday and today, I finally had the opportunity to do some real work on PopScan with Delphi 2005. Here’s what I really like besides the obvious:

  • Those .bdsproj-Files are incredibly useful. They replace the old DSK and DOF-Files, have a convenient XML-format and are the new project file, you open with in Delphi. This is very nice as the old project file (.dpr) is actually program code and does not contain any project metadata. This is what those .dof and .dsk-Files where used for, but I never understood which setting is in which and the format has not been XML either. So this consolidation really is convinient.
  • The history-feature really saved my day. With me hitting Ctrl-S on nearly every line I write, the older .~pas-approach wasn’t very useful and CVS was no help either because I don’t commit as often as something could go wrong in the code.
  • The new exception catching-dialog of the debugger is really nice. I like this “Dont halt on this exception again”-Checkbox.
  • While it makes the application significantly slower under the debugger, the new “event log” is great.
  • Speaking of debugging: The “Local Variables”-Window is great too.
  • Delphi now distinguishes between a “Default Layout” and a “Debug Layout”. You can configure both of them as you like and Delphi automatically switches between them. This is much more intuitive than before.
  • Maybe I’m the only person on earth, but I like the single-window-approch: It’s much cleaner than before. No more tons of clutter on the screen and the important screens are always wisible. No more Ctrl-Alt-F11 either.

Additionally, I don’t have as much speed problems as others seem to have: While starting the IDE takes it’s time, working with Delphi when it’s open goes quite smoothly.

My only problem is opening the form designer. This definitely takes too long, but not long enough for me to switch back to the undocked layout.

Memory usage is of no concern to me. I have 1 GB of RAM and even after a day of using delphi, my Thinkpad remains responsive even though not only delphi, but also eclipse, Zend Studio, Firefox and many other programs are running. For me the figure the task manager tells me is not nearly as important as the responsiveness. If delphi uses 500 MB of RAM, fine – as long as my PC stays responsive.

All in all, I really like this new Delphi and I already have uninstalled D7 (thus breaking FeedDaemon).

Delphi 2005

I got my hands on the demo-version of Delphi 2005 (download it here), and I actually have configured the beast already, so I have my usual environement to work on PopScan with it. These are my first impressions (I won’t talk about this File-Download-Window-Popping-Up Problem as all know it’s a nasty problem with a security-patch from Microsoft which will soon be fixed. Read about it here on Steves blog

  • It takes quite some time to start up. After removing the Delphi.NET and c# personalities (don’t need them), it starts about as fast, als my Delphi 7 did. Just a little bit slower
  • The compiler got faster, if you ask me.
  • Besides the great new features Borland is talking about, there are very nice usability-tunings everywhere which make working quite a bit easier.
  • The VCL form designer is extremely slow on my machine. Just displaying the PopScan Main Form within the designer takes nearly 10 Seconds. Delphi 7 does that instantly.
  • The debugger is slower too, which certainly has to do with the many great feature additions. I can live with that.
  • It’s extremely compatible to Delphi 7: I could install every single third party component without any problems. This is quite impressive considering Delphi 2005 is quite a rewrite.
  • While I like the new docked form designer, there’s one usability-problem with it: When you have components that use their own property editors (like Toolbar 2000), those editors are opened in their own window (understandable). Now, if you select a button in the component editor and then click the Project inspector to change a property, the Delphi Main Window will cover the property editor rendring it invisible. An easy fix would be to define the property editor always-on-top – a better fix would be integrating it somewhere in the IDE
  • Even JCLDebug could be compiled and installed (even the IDE Expert did work, though you have to manually install it)

All in all, this release of Delphi is a very great release providing the user with a ton of new features and fixes to long-standing usability problems (so long that you got used to them and now are missing them…). I have not expirienced any crashes so far (besides the one where the expat-parser of a debugged application took all the ram on my system, but I don’t blame Delphi for that), which is very nice.

Now, if only the beast could be made to run a bit faster (which will be done, I’d say, it’s the best Delphi since Delphi 2 which means quite a lot…

Thanks Borland.

PS: I know that it’s currently more in fashion to bash Borland and to whine about everything they do. And for the fourth consecutive year now I read posting about Delphi’s impending doom everywhere on the net. But consider this: Delphi still is the only RAD tool out there producing 100% native windows executables. And it still has one of the most lively communities I know of in the Windows-world. Even if Borland would kill off delphi, I’m quite certain, it will not go so easily. Not with this community.

On and speaking of killing off delphi: Seeing this great release of Delphi 2005, I am quite assured that Borland will continue supporting us.

So: Quit whining around!

Copying with MOVE? Moving with copy?

Today I came across the situation where I had to copy – using delphi – some chunck of memory from one place to another. I nevery did that before (using OOP techniques gets you around that most of the time – at least in Delphi), so I had no idea how to do it. What I knew is that in C, I’d do that with memcpy. As a convinced fan of Pascals intuitive API notation, I looked in the help for MemCopy or CopyMem. Nothing (which is strange, considering things like AllocMem actually exist).

Some googling around turned out the name of the function: it’s

procedure Move(const Source; var Dest; Count: Integer);

Move? That can’t be. Can it? I want to copy, not to move. A quick glance at the help file revealed that it’s the truth: Move actually copies…

Move copies Count bytes from Source to Dest. No range checking is performed. Move compensates for overlaps between the source and destination blocks.

Descriptive procedure names? Usually, yes. But this can only be described as way beyond the optimum ;-)

Oh… on another note: What do you think, Copy does? Copying memory? No way:

function Copy(S; Index, Count: Integer): string;

function Copy(S; Index, Count: Integer): array;

S is an expression of a string or dynamic-array type. Index and Count are integer-type expressions. Copy returns a substring or subarray containing Count characters or elements starting at S[Index]. The substring or subarray is a unique copy (that is, it does not share memory with S, although if the elements of the array are pointers or objects, these are not copied as well.)

If Index is larger than the length of S, Copy returns an empty string or array.

If Count specifies more characters or array elements than are available, only the characters or elements from S[Index] to the end of S are returned.

Yeah!. Right.

Oh and on second thought: The move-thing may have its roots in the assembler language, where MOV actually copies the data too – at least I think so. But anyway: If even C got it right, why has my beloved Pascal to fail in such an easy case?