Wednesday, July 27, 2011

Masochistic programming

I wrote three years ago about creating a unicode version of one of our exam programs. Recently it transpired that the program doesn't display Hebrew on some computers (all of which are running Windows 7) presumably because the Hebrew was displayed on a non-unicode dialog. It turns out that on some computers, Hebrew was not set as the non-unicode language; when this definition was changed, the programs were displayed correctly. Even so, there are still a few computers which don't display the Hebrew correctly. I tried to create a completely unicode  version of the program but it seems that the TNT components which I had been using don't display Hebrew correctly (if at all). One reason for this is that the resource file containing the Hebrew text was saved as ANSI, so it's not surprising that there were problems. But even after saving the resource file as unicode (and compiling it with the unicode resource compiler, GoRC), there were still problems.

There is a TUnicodeLabel component which I discovered which does display Hebrew unicode; unfortunately this component does not display right aligned text nor does it display multiple line text.

The answer of course is to update Delphi 7 to Delphi XE but the financial cost seems to outweigh the advantages. Not only that, every string would suddenly become unicode, a change which is liable to cause more problems than it solves.

The idea occurred to me to recreate the program as a standard WinAPI program in Delphi; this is a very masochistic programming technique as it obviates all the advantages that Delphi brings to the table. The only apparent 'advantage' is that the resulting executable file is very small, which might have been important once but now is meaningless. The program code is verbose and difficult to understand; this is how early Windows programs were written, until frameworks such as Delphi and Visual Basic appeared.  Using this technique, I was able to create my own unicode labels and have them display Hebrew correctly.

I discovered this site which gives tutorials into writing WinAPI programs in Delphi. Unfortunately the writing is not too clear (there is also the tendency to confuse its with it's which always annoys and distracts me) and the demonstration programs are presented in a way to defy comprehension, having more comments than code.

After struggling with these concepts for a few hours, I took the dog for a walk. As I have written several times before, this is a very therapeutic step and always helps when confronted with a programming conundrum. As usual, an idea popped into my head whilst walking: keep the Delphi program but add the unicode labels with low-level code. As the exam is very dependent on displaying data but not so dependent on receiving data, this would be a definite possibility to be examined. Can this be done, I wondered? Yes, indeed.

So from one dialog box, I removed the TNT labels and replaced them with calls to CreateWindoxExW. The downside of this is that I am unable to see the labels on the dialog during design time, but the technique does work. The labels at the moment are in a system font and have the wrong coloured background but such matters are not important at the moment. Once I  see how to display multiline text in such a label, I can make a full version of the exam program and send it to be tested on a computer which is known to display my programs incorrectly.

No comments: