Small questions

I get a constant stream of small questions about Delphi in my inbox. Some are easy to answer and usually just send a quick response others are more complicated. But why not share some of those answers with all of you?

1) How can I install an external ActiveX control (.OCX file) in Delphi?

  • Click File > New > Package – Delphi for Win32
  • Save the Package project.
  • Click Component > Import Component…
  • Select Import ActiveX control.
  • Select ActiveX-control in list or click Add and browse the for file.
  • Fill in component details, like name and palette page.
    • Optionally set unit directory to same location as where you saved the package project.
    • Optionally check Generate component wrappers.
  • Select Add unit to Package and Finish.
  • Right click on
    the Package in Project manager to Build and Install package.´

Why should I change where the unit is saved? Personally I prefer to have the package and its source in a folder under version control rather than have it stored in Delphi’s local import folder. It makes it easier for the rest of the team.

Turbo Delphi 2006 Professional users
Import Component and View>Type Library is missing because of a defect. Here is a workaround:

  • Create this directory: $(BDS)\include\atl\
  • Create an empty file named: ATLBASE.H

Turbo Delphi Pro now has the Component/Import Component and View/Type Library menu choices.

2) How do I get my application with Paradox tables to work on Windows Vista?

This one is a little bit tricky. There are several pitfalls here.

First of all you need to install BDE with your applications installer as usual. If you are using a comercial installer or call you installation executable setup.exe, Vista will detect that it is an installer and suggest running it as administrator which is needed to write files in the Program Files folder and the local machine registry.

Secondly, do you add global BDE-aliases for you database? They are stored in idapi.cfg file under Program Files where a standard user does not have the rights needed to alter files. It will work if you do this from the installer since it is running as administrator but if you add aliases from your application there might be trouble ahead! Windows Vista has a nasty compatibility feature called Virtualization or Redirection that will silently create personal copies of files instead of giving you an access denied error. Consider the administrative nightmare when every user has their own copy of idapi.cfg hidden in a personal VirtualStore folder. You can easily turn all compatibility features off by checking Enable runtime themes in Project > Options > Application in Delphi 2007 (or by manually adding a manifest). Remember that should always run the BDE Admin tool and control panel applet as administrator since running them as Standard User also will create a copy of idapi.cfg in the personal VirtualStore.

My suggestion is that you use a TDatabase component in you application instead of using global aliases and create a private alias for you application by setting DatabaseName and use DriverName and Params property instead of Alias property.

Next problem is the location of the database. If you have put you Paradox or dBase files it in the Program Files folder you will trigger Virtualization and then you have parts of the database in each users VirtualStore! Try to mend that mess into one database again. You should follow the steps above to add a manifest to your executable and get access denied errors instead of this mess.

Use the SHGetFolderPath function to get a path to a better location where Standard Users have read and write access. You will find an example of this in the File > New Other…> Win2000 Logo Application. Consider using CSIDL_COMMON_APPDATA if it is a shared database. You can easily get you installer to put you database files here instead by using pre-defined constants (i.e. [CommonAppDataFolder] in InstallShield, $ALLAPPDATA$ in InstallAware).

For Paradox there is the problem with NetFileDir. The default value “C:\” will not work. To get around this, add a TSession component to your application and set NetFileDir using a value from the SHGetFolderPath function. Use CSIDL_COMMON_APPDATA.

Finally, consider upgrading your Paradox or dBase database to InterBase instead! 🙂