Enabling international character support in a Western (or non Far East) edition of Windows for your Delphi 6 application

By: Chee Wee Chua

Abstract: This article describes how you can enable international character support in a Western (or non Far East) edition of Windows for your Delphi 6 application.Written by Chee Wee Chua

Suppose you have a client who has Windows 2000 installed. Your client is using a Western (or non Far East) edition of Windows 2000, and your client demands that your Delphi 6 application supports entering Far East (now known as Southeast Asia) international characters, such as Chinese, Korean, Japanese, among others.

Delphi defines a Western edition of Windows 2000 as one of the neutral, Danish, Dutch, English, Finnish, French, German, Italian, Norwegian, Portuguese, Spanish, Swedish language editions of Windows 2000. Refer to the IsWesternGroup function in the SysUtils unit for more details.

Before this article was published, you have no choice but to tell your client that there is no way you can deliver a Delphi 6 application on a non Far East edition of Windows 2000 that provides international characters support, because you have read the VCL source code and you know better.

Here's how you can enable international character support in your Delphi 6 application. The code for international character support for your application is found inside the Controls unit. Examining the source code for Controls unit shows that the core code for enabling international character support is run during the initialization phase of Controls unit. One step of the initialization phase involves calling a procedure named InitIMM32. This procedure checks the Boolean variable FarEast in the SysLocale record located in the SysUtils unit. No problem. What you can do is call InitIMM32 in anywhere of your project when you want to enable international support right? Eh, wrong. You can't call InitIMM32 because it is local only to the Controls unit.

In order to make sure that the international support is enabled, you have to make sure that before InitIMM32 is run, SysLocale.FarEast is set to true.

The variables in the SysLocale record is set in one of the following situations.
A call to GetFormatSettings is made.
The SysUtils unit is initialized for the first time.
When a WM_WININICHANGE message is received by your application.

When I tried inserting the statement SysLocale.FarEast := True; into the main project file as seen below, it didn't work, because, by the time the statement has been executed, the local procedure InitIMM32 in Controls unit has already been executed during it's initialization phase. Although when you look at your project uses statement, you do not see the Controls unit being used, the fact remains that the Controls unit has been included in your project. This is due to the fact that the Controls unit has been used both in the Forms unit, and also the MainForm unit, which contains, well, the main form.

program IME_Enabled_App;

uses
  Forms, SysUtils,
  MainForm in 'MainForm.pas' {Form1};

{$R *.res}

begin
  SysLocale.FarEast := True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Since the Controls unit is used by the Forms unit, this means that I have to write a unit whose initialization code is just to set SysLocale.FarEast to True and my unit's initialization code has to occur before the Control unit's. (This also means my unit has to be included in the main project file, just right before the Forms unit, as seen here.) I choose to call this unit, EnableIME.

unit EnableIME;

interface

implementation
uses SysUtils;

initialization
 SysLocale.FarEast := True;
end.

Beware! If you use the GetFormatSettings procedure, all of the SysLocale variables will be overwritten, so after making a call to GetFormatSettings, remember to set the SysLocale variables back to your desired values.

In order to allow your users to enter international characters in your application, you have to make sure that any control required to display international character's have it's ImeName and Font.Name property set. The font to be used has to be one that includes the international characters you intend to use.

In the sample application accompanying this article, I created a RichEdit control that supports Chinese characters. I set it's ImeName property to the first available value (which, on my system, is 'Chinese (Simplified) - MS-PinYin98') in the TStringList Screen.Imes class (which holds a list of all IMEs supported on the system) during the initialization of the main form. I've also set RichEdit1's font to 'NSimSun'.

I show my sample application running below.

Entering Chinese characters in a Delphi 6 application

You should be able to adapt the code in this article to work with earlier versions of Delphi or Borland C++ Builder. The code for this article was tested on Windows 2000 Professional, with Delphi 6. This code should work fine on Windows XP, Windows 95, 98 and ME too.

With this article, I hope you will now be able to add international character support to your Delphi 6 applications.

Chee Wee lives in Singapore. He works at Right Security Consultants, a company providing network security services and seminars. He can be reached at chuacw@rightsecurity.biz.


Server Response from: ETNASC04