4
votes

I'm using Delphi Seattle with the theme of Windows 10, creating programs for Windows Desktop.
In a TEdit if the active NumbersOnly property, when trying to type words, you see a standard Windows hint.
If I leave the program without the theme, the hint appears correctly, with the message explaining that you can only enter numbers. But if the active theme the message is unreadable.

Anyone have any idea where I can change this, because I was looking inside the Vcl.StdCtrls.pas and could not find the time that is generated this message to the user.

Correct hint:

enter image description here

Wrong hint: enter image description here

3
My guess the hint message is generated by windows itself not by the vcl. Maybe you can write your own handler to accept only numbers an example can be found here: stackoverflow.com/questions/6896870/…Hans Harz
Yes, that is a system-level hint, not a VCL-level hint. The NumbersOnly property is merely enabling the ES_NUMBER window style.Remy Lebeau
Thanks, i used the VCL Styles Utils, a lot of edits with numbersOnly property in project.Rafael Rossi

3 Answers

9
votes

This issue was fixed in RAD Studio 10.1 Berlin. But if you can't upgrade your RAD Studio Version try the VCL Styles Utils project which includes a fix for this. Only you need add the Vcl.Styles.Utils.ScreenTips unit to your project.

enter image description here

2
votes

Update to Delphi 10.1 (Berlin) - it seems to be fixed there as I cannot reproduce this while I can with 10.0 (Seattle).

The bugfix list for Berlin shows several issues being fixed that are related to VCL Styles.

2
votes

A workaround for this is to not rely on the rather useless Microsoft implementation behind the ES_NUMBER style, but implement your own logic.

type
  TEdit = class(VCL.StdCtrls.TEdit)
  protected
    FInsideChange: boolean;
    function RemoveNonNumbers(const MyText: string): string;
    procedure KeyPress(var Key: Char); override;
    procedure Change; override;
  end;

  procedure TEdit.KeyPress(var Key: Char);
  begin
    if NumbersOnly then begin
      if not(Key in ['0'..'9','-',#8,#9,#10,#13,#127]) then begin
        Key:= #0;
        //Put user feedback code here, e.g.
        MessageBeep;
        StatusBar.Text:= 'Only numbers allowed';
      end else StatusBar.Text:= '';
    end;
    inherited KeyPress(Key);
  end;

  procedure TEdit.Change; override;
  begin
    if FInsideChange then exit;
    FInsideChange:= true;
    try
      inherited Change;
      Self.Text:= RemoveNonNumbers(Self.Text);
    finally
      FInsideChange:= false;
    end;
  end;

  function TEdit.RemoveNonNumbers(const MyText: string): string;
  var
    i,a: integer;
    NewLength: integer;
  begin
    NewLength:= Length(MyText);
    SetLength(Result, NewLength);
    a:= 1;
    for i:= 1 to Length(MyText) do begin
      if MyText[i] in ['0'..'9'] or ((i=1) and (MyText[i] = '-')) then begin
        Result[a]:= MyText[i];
        Inc(a);
      end else begin
        Dec(NewLength);
      end;
    end; {for i}
    SetLength(Result, NewLength);
  end;

Now non-numbers will not be accepted, not even when pasting text.