The Delphi Bug List

Entry No.
326
External
TMaskEdit causes a keyboard lock on some machines and a big slowdown and blinking numlock on others.
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
ExistsExistsExistsExistsExistsExistsExistsExistsExistsExistsUnknownUnknownUnknownUnknownUnknown
Description
By Anita-Maria K. Parolla, Christian Wiedemann, Paul Shepherd, Rogério Jacques, Rune Moberg. Fix by Stefan Hoffmeister
Anita-Maria K. Parolla wrote:
In some computer/keyboard combinations (I isolated my problem to only those that have a ps2 bus, and not all of them) pressing a key (usually a number) causes to keyboard lock. I did not have this problem with regular TMaskEdit component but than I hardly ever used this component.

I have a large number of clients that use my software (all over America). I would say that about 6 of them reported the problem. At the beginning I thought it was a particularly bad joke and the people just do not know how to use a computer. But one of them realized I do not take him seriously and shipped me his entire box (NEW system: Hewlett Packard, Pentium 133 MHz, PS2 keyboard and PS2 mouse, Windows 3.11). Gosh, I got the shock of my life! Since then the problem is spreading because they buy brand name new computers (Compaq, Hewlett Packard, companies who switch from the old serial mouse to PS2 Mouse and keyboard).

BTW, I subscribe to ddj-thread listserv (from cobb tips etc) and I once uploaded a question about this problem. Apparently some other people have seen it, too, and they informed me it was a bug in Delphi. I talked also to Borland. They deny it is their problem, they said it happen because of an old faulty keyboard. Actually I understand them. I did not believe either until I saw it with my own eyes. And regarding "an old faulty keyboard" claim. Sorry! Six absolutely new computers - brand name new computers (!). But it does not happen on all computers with PS2 bus. I have a Gateway 120 MHz with PS2 bus. Worked perfect! I took my keyboard (which worked properly with my machine) and put it on the computer with the problem and VOILA suddenly my good keyboard is an "an old faulty keyboard".

Christian Wiedemann wrote (16 Apr 1997):
This happens in Delphi 1 under Windows 3.1 on my P133 (Ok under 95 or on my 486DX2/66). Build a new form with a TMaskedit on it. I define any mask at design time (phone number for example). At run time, while entering data in the field, the keyboard gets locked (the numlock led is then turned off) and cannot be recovered (even after leaving the application and windows with the mouse) until rebooting the PC. Sometimes I can get out of this situation by double clicking in the field (the numlock led is turned on again and the keyboard is unlocked). Another surprising thing: if I do unlock the numerics (numlock key pressed to switch the led off) before typing anything in the field, it's ok.
This happens also with the TStringGrid component, allowing editing the cells and specifying an edit mask at runtime in the OnGetEditMask event. At last, if I don't use a mask, everything is allright....

Paul Shepherd wrote (23 June 1998):
I have had the same problem using Delphi 3.02. (Although the lock isn't permanent - it just makes the edit box run very slowly.)

Rogério Jacques wrote (6 October 1998):
I found the bug described by Anita-Maria and Christian and it occurs in all versions of Delphi and the correction described by Stefan Hoffmeister works in all versions. Thanks to Stefan.
Regards,
Rogerio

Rune Moberg wrote (18 Jan 1999):
I have additional info about "TMaskEdit causes keyboard lock on some machines".
Turns out that on the Intel SE440BX motherboard (with earlier BIOSes) and other BX/EX based Intel motherboards there is a problem calling SetKeyboardState with a null array (which is what TCustomMaskEdit is doing). Stefan's workaround seems to work ok though.
Dell btw uses a modified SE440BX motherboard and can't use Intel's own BIOS upgrades (atleast not directly). Dell's own BIOS upgrades (as of this date) does not incorporate any fix.
The problem is that a call to SetKeyboardState takes approx 500ms when a null array is used as argument. The Win32 API help states that: "Because the SetKeyboardState function alters the input state of the calling thread and not the global input state of the system, an application cannot use SetKeyboardState to set the NUM LOCK, CAPS LOCK, or SCROLL LOCK indicator lights on the keyboard. " But this is false. Num Lock was indeed affected. (hence when loading a form with lots of masked edits, numlock started blinking on the user's computer for several seconds!)
NT is a different beast entirely and is not affected. SetKeyboardState works as documented (doesn't affect status indicators) on all machines tested.
In September (or so) there was quite an uproar on the Intel newsgroups, because several users were unable to use their keyboard with Win98 using the current BIOS upgrade at that time. I believe Intel addressed this issue and also straightened out the SetKeyboardState (perhaps inadvertently?) problem as well.

Solution / workaround
Stefan Hoffmeister came up with this:
The following is the proposed solution to the TMaskEdit problem you are listing for Delphi 1. It has been posted on the newsgroups by many people and I really cannot point to the original authors. As I have never seen the problem MYSELF I cannot say whether the solution actually fixes the problem - the posters do claim though that this is the case. Since publication of the fix (below), reports have been received that it does fix the problem (RPS)

Solution:
One fix could be to change the VCL source code in MASK.PAS according to the following example:

procedure TCustomMaskEdit.SetCursor(Pos: Integer);
var
...
begin
...
    SetSel(SelStop, SelStop);

    if SelStart <> SelStop then
    begin
      GetKeyboardState(KeyState);

{$IFDEF FixMaskEdit}
      NewKeyState := KeyState;
{$ELSE}
      for I := Low(NewKeyState) to High(NewKeyState) do
        NewKeyState[I] := 0;
{$ENDIF}
      NewKeyState [VK_SHIFT] := $81;
      NewKeyState [VK_LEFT] := $81;
      SetKeyboardState(NewKeyState);
...
David S. Becker (dsb@plaza.ds.adp.com) has another fix for the same problem:
      GetKeyboardState(KeyState);
{$IFDEF FixMaskEdit}
      NewKeyState := KeyState;
      NewKeyState[VK_CONTROL] := $00;  { Up }
      NewKeyState[VK_MENU] := $00;  { Up - ALT key }
      NewKeyState[VK_SHIFT] := $80;  { Down }
      NewKeyState[VK_LEFT] := $80;  { Down }
{$ELSE}
      for I := Low(NewKeyState) to High(NewKeyState) do
        NewKeyState[I] := 0;
      NewKeyState [VK_SHIFT] := $81;
      NewKeyState [VK_LEFT] := $81;
{$ENDIF}
      SetKeyboardState(NewKeyState);
Now, the fixes given above are only useful to people who are able to recompile MASK.PAS. However, many people can't do that and have asked how the could obtain a fixed MASK.DCU.
To meet those requests, here's a copy you can download: mask.dcu; accompanied by a text file with instructions: mask.txt.
User-contributed comments
Tony Christiansen tony@accomplish.com.au
17 May 2001  10:55 PM GMT
I have users report that this bug still exists in v5.01. The VCL needs the patch

Regards
Michael Haralabos
23 May 2002  02:22 AM GMT
Exists on Delphi 6.02 too (see the source code).
Someone kindly can post it on Quality Central.
Michael Haralabos
07 Jun 2002  09:50 PM GMT
Posted on Quality Central!
Latest update of this entry: 1999-11-10

Post a comment on this bug


Index page
Delphi Bug List home page
The Delphi Bug Lists are presently maintained by Jordan Russell, who has taken over this task from Reinier Sterkenburg since August 2000.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.