Delphi, WinXP and Password Edits

I’m still into making Delphi apps look more “native” when run under Windows XP. Now that I got the IE-Control working, I was looking into the password-edit case.

The Problem: When using the standard way for creating password edits (Drop a TEdit on the Form and set the PasswordChar property to ° ), this may look and work on in Win 9x, NT and 2000, but under XP, some features are missing:

  • In XP, password-edits cannot be read from other applications by sending the WM_GETTEXT message. Delphi’s TEdit can.
  • In XP, the edits have a nice bullet instead of a * to mark the entered characters
  • When CapsLock is active, a balloon-hint appears warning the user that maybe she is not doing what she expects

    How to fix this?

    Simple: Create a descendant of TEdit, override CreateParams and set the controls style to ES_PASSWORD. Provided you are supplying a valid Manifest for XP, you now have a fully fledged and nice working password-edit:

    procedure TPasswordEdit.CreateParams(var Params: TCreateParams);
    begin
      inherited;
      Params.Style := Params.Style or ES_PASSWORD;
    end;
    

    Oh. One thing is still missing: The dots look wrong. This is because Delphi does not use Windows’ standart font per default but overrides this with “MS Sans Serif” where “Tahoma” is the standard under XP. So Delphi-Apps generally look kind of foreign – even more so, when ClearType is enabled (MS Sans Serif is a bitmap font and cannot be antialiased).

    This can be fixed by setting each forms DesktopFont property to true. Note that it’s a protected property, so it must me called from withing the form.

    Now the bullets look right and the font’s in your application are proper anti-aliased (provided ParentFont is set to true in every component on the form).

    delphi_pwchar.png

Delphi, Windows XP, Styles and embedded IE

Let’s say you have a delphi (delphi 7 – altough prior versions can use Mike Lischkes Theme Manager application which embedds the Microsoft Internet Explorer ActiveX Control. Let’s assume furhter that you have created your Manifest so the application appears in the themed style under Windows XP.

Unfortunatly, the embedded IE does not do that: Controls are still drawn in the old theme-less style. Why? How to tell the Control to use the themed style (which it certainly supports – just look at IE itself)?

For long I was looking for a solution which I’ve just found.

First, call SetThemeAppProperties (defined in UxTheme.pas), then send WM_THEMECANGED to your forms – at least to the one that uses the IE-Control. Example:

  SetThemeAppProperties( STAP_ALLOW_NONCLIENT OR
       STAP_ALLOW_CONTROLS OR
       STAP_ALLOW_WEBCONTENT );
  PostMessage(frmBrowser.Handle, WM_THEMECHANGED, 0, 0);

Especially important is the flag STAP_ALLOW_WEBCONTENT

Then, in the form containing the browser, just add a message-procedure:

Form-declaration:

  private
    procedure wmthemechanged (var msg: TMessage); message wm_themechanged;

Update: I’ve turned off the comment-feature as this entry somehow got listed in some spammers database. I’m currently deleting about 10 entries per day that are just there to provide links to some stange sites. I’ll post about this later.

Gentoo on a xSeries 235 Server

Yesterday, one of the harddisks (or was it the SCSI-Controller – it does not matter…) of our very old, self-assembled developement/fileserver went down. As we had backupped the important data and I had a spare PC running Linux (the multimedia machine I wrote about here), getting a working environement was a matter of about two hours (one I used up trying to get the old server to boot again).

Anyway: We deceided that it was time to move away from self-assembled machines to something more professional (and hopefully more reliable), so we ordered a IBM (we really like those machines – great support, long warranty and rock-solid) xSeries 235 machine which arrived today.

I deceided to install Gentoo Linux on the machine as it will mostly be used as my developement server (and as a windows-fileserver for our data), so eventual downtimes do not really matter (but latest versions of the installed software are important) – a nice testbed for this distribution until I roll out production machines running Gentoo.

Besides the hardware-RAID5 the new server had built in, we plugged an old 120GB IDE drive to be used as storage area for not-so-important files (read: music, temporary files,…) – additionally it contained all the current developement work, so I had to copy it’s contents down to the new virtual RAID5 drive.

Installing was quite easy, but unfortunatly, the current gentoo-sources kernel (2.4.20 – heavily patched) does not support the DMA-Mode for IDE-Devices on the onboard chipset (ServerWorks something), so copying about 30 GB of data from the IDE drive to the RAID was not funny and neither was doing anything on the server when transfers to the IDE drive where running. It was slooow!

Installing a current 2.4.22 vanilla-sources kernel solved the DMA-Problem but raised another: The xSeries 235 uses a Broadcom bcm5700 Gigabit Ethernet chipset which is not supported under a vanilla kernel. Of course, I forgot to patch the driver in before I rebooted the newly created kernel which forced me to go down to the basement, compile the driver and go up here again to write this text.

Anyway: The server is now working like a charm. I really look forward to really use it and to take advantage of the greatly increased speed (PII 500 Mhz -> Xenon 2.6 Ghz and more than twice as much RAM than before)

Just another debian install

Today I was going to install Debian Linux on another of those IBM xSeries 345 servers.

I really like those products as they are quite powerful and use only two units in your rack anyway. And they are rack-mountable without screws which makes the whole process quite a pleasure.

The problem when installing those machines is that Debian 3.0 does not support the built in ServeRAID controller. There is an extended boot-floppy on http://people.debian.org/~blade/install/preload/, but unfortuantly, today people.debian.org is down.

My solution was to apt-get install kernel-headers-2.4.18-bf2.4 (on another debian machine), to download vanilla 2.4.18 kernel sources, to copy over /usr/src/kernel-headers-2.4.18-bf2.4/.config to the directory where I unpacked the vanilla sources, to make oldconfig, to make menuconfig, to select Support for IBM ServeRAID in the configuration tool and finally to make modules.

I then copied the compiled ips.o to a blank disk in a directory called /boot. I could later on use this disk in the debian installation process (booted from CDROM with bf42 on the bootprompt) when I can “Load essential modules from disk”.

I did the about same thing for the e1000 driver, the built in ethernet chipset requires:

  • Download it here and uncompress it.
  • Hack src/Makefile to use the kernel-sources above.
  • make
  • ignore the warning that a module not matching the current kernel will be built (because that’s what I want)
  • Copy e1000.o to the disk

    Now it installs flawlessly and I’m quite happy…

How to get a Lamp

Last sunday, the lamp of my IBM iL2220 video projector (no link as it is neither available nor would I recommend it any more) exploded. This was especially stupid as I just bought Wario World and Metroid Prime (which I had to have after finishing Metroid Fusion on my GBA and getting to know this wonderful series) and I really wanted to play them.

On Monday, I called IBM’s support line and asked for the part number of the replacement lamp to be able to buy it at the IBM distributor our company has an account at. The supporter told me that he would need the serial- and partnumber of my projector which I did not know.

Today I finally wrote down those numbers before I went to the office and gave IBM another call.

This time the supporter told me (without needing the neither partnumber nor serial number this time) to call another number, which I did thereafter.

This time I was in one hell of a callcenter menu requiring me to press buttons, giving my name and finally my phonenumber for an automated callback. When I finally had a human on the other end of the line (of course I had to make the phonecall with my cellphone – our PBX does not support DTFM sequences), he laughed at me and told me he was from software support and whether he should “flash” my defunct lamp. Funny, but not after having to wait 30 minutes for it ;-)

Anyway: I got another number where I called later on.

This time the supporter knew what I was speaking about (after having explain to her for about three times that I knew the warranty has expired and that I just want the part number to place an order for another lamp). She told me that she was not allowed to give out any part numbers but that she would try to help me anyway.

20 minutes stupid music

“hmmh… please hold the line. This is complicated”

another 10 minutes

Finally she told me that she will connect me to someone else that knows what to do.

2 Minutes

Now I had another supporter at the phone. I told my story again and she finally gave me this stupid part number (33L3426) which the previous supporter was not allowed to give me.

In the webshop of our IBM retailer, I learned that the lamp would cost ~CHF 700.- and that I would have to wait at least 20 days for the new lamp to arrive. Not good as I really want to play Metroid Prime.

Using google I learned that the IBM iL2220 is nothing more than an inFocus LP350 with an IBM label on top of it. Something worth to give a try with.

The supporter at inFocus gave me the number of a retailer of theirs, I called them and learned that they have a lamp on stock and that it would cost at most CHF 485.- more than CHF 200 less than the IBM lamp. Needless to say that I’ve placed my order. The lamp will arrive on friday – about 10 times sooner than the IBM lamp would have arrived.

So much to the great IBM support. So much for buying an IBM product to have a good supply in replacements.

SOAP needs soap

For our Web-Portal superspeed, I am working on a webservice to give some clients access to our provider/offer database.

As the whole portal is written in PHP, I deceided to write the Webservice (fully fledged using the SOAP-Protocol) in PHP too. After some searching, found NuSOAP and the SOAP-Package in PEAR.

Both packages have virtually no documentation, but the PEAR-package has some nicely documented samples (disco_server.php, example_server.php just to name the most interesting two).

While nuSOAP is very easy to handle, it doesn’t have a way to autogenerate WSDL-output which would have forced me to learn writing WSDL. Unfortunatly I did not have time for this, so I went with the PEAR-Package which is able to create the WSDL for you.

The first tests using PHP as SOAP client worked very well.

tip: to increase “debugability” to an actually useful level, use something like the code here for debugging your server:

// include the actual server class
require_once 'modules/ss3_Provider/xml_access.php';

if ($_SERVER['argv'][1] != 'direct'){
    // use the SOAP-Interface to our class
    include("SOAP/Client.php");
    $wsdl = new SOAP_WSDL("http://your.server.com/server.php?wsdl");
    $object = $wsdl->getProxy();
}else{
   // Use the class directly
    $object = new CProvServiceInfo_Class();
}
// do something with $object

If the script is called with the “direct” parameter, the class will be used directly thus giving you back all the debug information you need without an XML-parser trying and failing to unserstand them.

As the customer for this service is going to use ASP.NET to access the webservice, the next step was to try accessing the service via Visual Studio.NET. This was not fun (pasting the complete error here in the hope that google will catch this and will help future users having my problem):

Custom tool warning: At least one import Binding for the ServiceDescription is an unsupported type and has been ignored.

The hairy thing: I have no expirience at all with VS.NET, so I first thought this was a minor problem and I was just too stupid to actually use the imported class. But sooner or later (after trying out importing the Google Webservice), I came to the conclusion that this warning actually is a grave error: Nothing got imported. Nothing at all.

Searching google did not yield any results.

The next step for me was to learn WSDL (which I did not want to in the first place ;-). Unfortunatly, the PHP generated WSDL-File seemed quite ok (besides the missing <documentation>-Tags).

I could not get VS to report a mor detailed/useful error message.

Just when I wanted to give up, i thought of this tool, wsdl.exe that gets installed with the .NET Framework SDK. Running wsdl <filename.wsdl> gave me the same error message, but with a note to look into the generated .cs-File.

This finally gave an usable error-message:

// CODEGEN: The binding 'SuperspeedProvidersBinding' from namespace 'urn:SuperspeedProviders' was ignored. There is no SoapTransportImporter that understands the transport 'http://schemas.xmlsoap.org/soap/http/'.

A quick comparison of the <soap:binding&gt-Tags showed:

Googles Version: http://schemas.xmlsoap.org/soap/http
PHP’s Version: http://schemas.xmlsoap.org/soap/http/

Note the slash at the end.

I hate problems with simple solutions that are so awfully difficult to find because of un-usable error messages!

Just for reference: The following patch fixes the wrong Transport-URL in PEAR::SOAP (0.7.3 – I will report this to the author, so maybe it’s fixed in later versions):

--- Base.php    Thu Jun  5 13:16:03 2003
+++ -   Fri Jun  6 22:51:08 2003
@@ -91,7 +91,7 @@
 define('SCHEMA_DISCO_SCL',          'http://schemas.xmlsoap.org/disco/scl/');

 define('SCHEMA_SOAP',               'http://schemas.xmlsoap.org/wsdl/soap/');
-define('SCHEMA_SOAP_HTTP',          'http://schemas.xmlsoap.org/soap/http/');
+define('SCHEMA_SOAP_HTTP',          'http://schemas.xmlsoap.org/soap/http');
 define('SCHEMA_WSDL_HTTP',          'http://schemas.xmlsoap.org/wsdl/http/');
 define('SCHEMA_MIME',               'http://schemas.xmlsoap.org/wsdl/mime/');
 define('SCHEMA_WSDL',               'http://schemas.xmlsoap.org/wsdl/');

As you can see, there are more URLs having a slash at the end – possibly more candidates? We’ll see. At least I know now, how to debug such problems…

Just like SMS – only cheaper

When surfing around on my-symbian.com, I came across myBuddies, a free ICQ client for the P800. Most surprisingly it works quite well (I did my first testing with an active link to my desktop PC to avoid senseless GPRS charges).

What may look like a little toy is quite useful actually: GPRS connections are payed for transmitted data not for connection time so I can stay connected to the network without much cost and reach most of the people I usually send SMS to via the internet.

So let’s do a little calculation how many caracters I can send via ICQ to be as expensive as an SMS:

Swisscom currently charges CHF 0.20 for a SMS (max. 160 characters as you know). According to the current price list you get 10KBytes GPRS transfer volume for the same price which corresponds to 10240 Bytes. Subtract a protocol overhead of about 20%, you still get 8192 Bytes for the same price as an SMS – that’s 51 times cheaper than an SMS!

Drawback: Swisscom charges at least 10KB for every connection, so I will try to stay connected ;-)

Of course, if I’d switch to Sunrise it would get even cheaper: There is no 10 KB-Limit and it’s just CHF 7.50 per MByte (CHF 0.07 per 10 KBytes) so it’s 3 times cheaper than Swisscom [note to myself: I really should switch! NOW!] which means 8192*3 = 24576 Bytes for the same price as an SMS.

You get the idea how cool this seemingly senseless ICQ-Application for the P800 can be ;-)

If only someone would release a Jabber client allowing me to connect to my own pet jabber-server… Or maybe it’s time to really begin brushing up my Java-knowledge?