Archive for the ‘Delphi 2007’ Category

Scaling Between Large and Small Fonts

Wednesday, February 11th, 2009

I recently needed to be certain that my Delphi application would work the same whether the user selected ‘Normal” or ‘Large’ fonts in their Windows display properties.  I read the documentation and it appeared as though is should all work reasonably well  as long as the form’s Scaled property were True.  So, I set the property to True, changed my system to large fonts and let ‘er rip.  Guess what, it didn’t work.  The form’s caption and menus changed, but the controls that I placed on the form did not.  What the heck??

Much debugging and gooling later, I discover that there are two places in the Display Properties dialogue where you can select Normal or Large Fonts.  If you use the most obvious place, namely the Appearance tab, only form titles, menus and certain system dialogues change.  If you use the Advanced dialogue on the Settings page everything changes.

Windows!!!!

Why there would be two settings for the same thing that give different results I can’t imagine.

Creating a Form Wizard - Part 2

Tuesday, February 10th, 2009

In the last article, I described a way to make a TForm (or TFrame) descendant and register it with Delphi as a custom module.  This is all well and good, but forms and frames don’t appear in the tool box like other Delphi components.  They appear in the repository.  So, how to make the custom form or frame appear in the repository as though it were a native Delphi component?

The answer lies in the Open Tools API (OTA).  You need to create a Form Wizard using this poorly documented interface to Delphi’s IDE.  The coding itself is not particularly difficult but finding up to date documentation for the OTA is next to impossible.  Here is what I have been able to find out after a lot of googling.

(more…)

Creating a Form Wizard - Part 1

Wednesday, January 28th, 2009

It is often nice to have a form’s contents persist from one end user session to another.  Delphi provides for saving a form’s properties and contents from one design time session to another and loading those settings and contents as the form’s initial values when the containing application starts, but it doesn’t provide a means of saving and restoring a form’s settings and contents from one end user session to the next.  So, I decided to embark on a project to figure out how to provide this functionality myself.  Having a fair bit of experience writing custom components for Delphi, I thought “How hard can this be?”.  It turns out to be quite difficult if you want to do it right.

(more…)

Working with ActiveX Controls in Delphi 5

Friday, December 12th, 2008

I have a number of ActiveX controls that I have written in Delphi 5.  These things have been stable for so long that when I had to make a change to one recently, I found that I had completely forgotten how to re-import the control into the Delphi IDE.  It’s not that this is difficult to do but it is a tad obscure.  So, just in case I forget how to do it again, I am going to document the procedure here.

(more…)

TinyDB and Primary Indices

Monday, December 8th, 2008

Every time I use the TTinyDB component I get bitten by the same bug (or feature depending on your view point).

When you create a TinyDB table, it automatically creates a primary index using the first autoincrement field that it finds in the table.  Any index that you may have defined in IndexDefs with the ixPrimary option set is ignored.  User defined indices with ixPrimay set are ignored even if there is no autoincrement field and hence no automatically generated primary index.  Every time I run across this bizarre behaviour I waste the better part of a day trying to figure out what the heck is going on.  So this time, I am writing it down in the hopes that next time I will remember.

ISAPI Applications that Refuse to Run - Revisited

Wednesday, December 3rd, 2008

In my last post on this topic, I stated that it appeared as though IIS was not switching to the internet guest account properly. After much aggravation we finally discovered that the problem had nothing to do with the internet guest account’s permissions. The actual problem was a faulty printer driver, believe it or not. One of the printer drivers had a memory leak that eventually caused the kernel non-paged pool to become exhausted. Once that happens, IIS stops processing web requests. We downloaded and installed the latest versions of all of the printer drivers and the problem seems to be gone. Fingers crossed.

ISAPI Applications that Refuse to Run

Friday, November 14th, 2008

One of my customers developed an interesting problem the other day.  None of their ISAPI applications would run.  Any attempt to use an ISAPI DLL would hang and eventually time out.  IIS was not logging any errors to the IIS log files or the system event log.  It was a genuine mystery.

By inserting code that wrote progress messages to a trace file I was able to determine that the DLL was being initialized but the HTTP request was not being processed.  I could see code in the project’s main (.DPR) file being executed, then the TISAPIApplication.GetExtensionVersion method was being executed but that was it, TISAPIApplication.HTTPExtensionProc was never executed.

It took me a very long time to realize that IIS was failing when trying to switch to the internet guest account before executing HTTPExtensionProc.  I never did figure out what happened to the internet guest account, but by changing the ISAPI DLLs to execute using a ‘real’ user id rather than the internet guest account I got everything working again.  Go figure.

BLOB not found errors using Firebird and IBObjects

Tuesday, October 28th, 2008

One of my applications suddenly started throwing “BLOB not found” errors apparently at random. After some hours spent googling I came up with a cause for the problem but no solution. A bit of fooling around came up with a workaround. A fix for IBObjects would be better, but this at least gets rid of the problem. (more…)

Installing IBObjects into Rad Studio 2007

Thursday, October 16th, 2008

Installing IBObjects into Rad Studio so that the components appear in the Delphi tool palette is simple.  Just following the instructions in the help file.  However, getting the components to appear in the C++ tool palette is another matter altogether.

To get the components to appear on the C++ tool palette you need to make some changes to the projects for the design time packages.  Open each design time package (.DPR) project and open the project options dialog.  You need to select the Generate all C++Builer Files option in the linker section and you need to set the Search Path in the Directories/Conditionals section to the IBObjects source directory.

Once you have done these two things, just install the design time packages in the usual manner.   Simple when you know how but I spent an incredibly frustrating couple of days trying to figure this out.

Indy URL Encoding Bug

Saturday, September 13th, 2008

The TIdURI.ParamsEncode method in the version of Indy that ships with Rad Studio 2007 fails to encode all restricted characters. According to RFC1738:

   Thus, only alphanumerics, the special characters "$-_.+!*'()," (double
   quotes excluded ed.), and reserved characters used for their reserved
   purposes may be used unencoded within a URL.

Unfortunately, rather than encoding everything that is not allowed in the above list, ParamsEncode tries to identify specific characters which should be encoded, and the list that it uses in incomplete. Some snippets from the code illustrate my point:

const
UnsafeChars = ‘*#%<> []’; {do not localize}

if ((CharIsInSet(ASrc, i, UnsafeChars)) or (not (CharIsInSet(ASrc, i, CharRange(#33,#128))))) then
begin {do not localize}
Result := Result + ‘%’ + Sys.IntToHex(Ord(ASrc[i]), 2); {do not localize}
end

So ParamsEncode only encodes those characters that are in UnsafeChars or those that fall outside the range #33..#128. Unfortunately, several restricted characters (like double quotes) are inside the range #33..#128 and are not included in UnsafeChars and hence to do not get encoded. Bummer.

As an expedient fix I have taken to calling ParamsEncode and then fixing the characters that got missed in my own code. Longer term, I want to fix ParamsEncode, but that is for another article when I have more time.