Programmatically show a hint on the ball only for invalid text input

I'm following this example: http://lawrencebarsanti.wordpress.com/2009/12/16/display-error-messages-with-tballoonhint/

I am trying to show only the balloon when the current value in the edit box is not acceptable. The check is triggered when OnExit

. The balloon is still allowed to be displayed until the value is determined to be OK. I am also trying to programmatically show the balloon as soon as the user leaves edit to show the initial error.

The code works, but not the first time. I have to go away once with an invalid value, change to an acceptable one, then go back and use the invalid value again. I think this is because I cannot enable or disable the ShowHint property right before trying to show the balloon.

Here is my code:

procedure TForm1.Edit1Exit(Sender: TObject);
var
  R: TRect;
  Bad : Boolean;
begin
  //Check if edit has only numbers
  if StrIsReal(Edit1.Text) then
  begin
    if(StrToFloat(Edit1.Text) >= 0.5) then
    begin
      //Value is ok
      SpeedButton1.Visible := false;
      Edit1.ShowHint := false;
      BalloonHint1.HideHint;
      Edit1.Text := FloatToStrF(StrToFloat(Edit1.Text), ffFixed, 8, 2);
    end
    else
    begin
      //Is decimal, but not at least 0.5
      Bad := true;
    end;
  end
  else
  begin
    Bad := true;
  end;

  if Bad then
  begin
    //Invalid number
    Edit1.ShowHint := true;

    Edit1.Text := '0.00';
    SpeedButton1.Visible := true;

    R := Edit1.BoundsRect;
    R.TopLeft := ClientToScreen(R.TopLeft);
    R.BottomRight := ClientToScreen(R.BottomRight);
    BalloonHint1.ShowHint(R);   //!!! Issue: No hint the first time around
  end;
end;

      

How can I show the balloon conditionally correct when I check the actual value (leaving editing)?

+3


source to share


1 answer


Actually, the thing that is strange is that you get something the second time, and not that you don't get anything the first.

Your code works for me (in XE4 and XE6) the first time (and second) with this change:

  R := Edit1.BoundsRect;
  R.TopLeft := ClientToScreen(R.TopLeft);
  R.BottomRight := ClientToScreen(R.BottomRight);
  BalloonHint1.Description := 'bad input';   <---- this was missing
  BalloonHint1.ShowHint(R);   //!!! Issue: No hint the first time around

      



So, if it worked for you the second time around, I guess it is because of the code you are not showing and equally what you are not showing is probably why it does not work in the first place. So you can "spot the difference" with my project code below. I couldn't find your StrIsReal function, so I made my own.

Btw, I added a second TEdit to my form so there is something else to lose focus, and commented out your two Edit1.ShowHint assignments as they don't make any difference but shouldn't be needed anyway.

  TForm1 = Class(TForm)
  [...]
    FBalloonHint : TBalloonHint;
    procedure WMActivateApp(var AMessage: TMessage); message WM_ActivateApp;
    procedure WMWindowPosChanged(var AMessage: TMessage);  message WM_WindowPosChanged;
  [...]
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FBalloonHint := TBalloonHint.Create(Self);
  FBalloonHint.HideAfter := 5000;
  FBalloonHint.Delay := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  R: TRect;
begin
  FBalloonHint.Description := 'You pressed ' + Button1.Caption;
  R := Button1.BoundsRect;
  R.TopLeft := ClientToScreen(R.TopLeft);
  R.BottomRight := ClientToScreen(R.BottomRight);
  FBalloonHint.ShowHint(R);
end;

procedure TForm1.Edit1Exit(Sender: TObject);
var
  R: TRect;
  Bad : Boolean;
  F : Double;

  function StrIsReal(S : String) : Boolean;
  begin
    Result := True;
  end;

begin
  //Check if edit has only numbers
  if StrIsReal(Edit1.Text) then
  begin
    if(StrToFloat(Edit1.Text) >= 0.5) then
    begin
      //Value is ok
      SpeedButton1.Visible := false;
      //Edit1.ShowHint := false;
      FBalloonHint.HideHint;
      Edit1.Text := FloatToStrF(StrToFloat(Edit1.Text), ffFixed, 8, 2);
    end
    else
    begin
      //Is decimal, but not at least 0.5
      Bad := true;
    end;
  end
  else
  begin
    Bad := true;
  end;

  if Bad then
  begin
    //Invalid number
    //Edit1.ShowHint := true;

    Edit1.Text := '0.00';
    SpeedButton1.Visible := true;

    R := Edit1.BoundsRect;
    R.TopLeft := ClientToScreen(R.TopLeft);
    R.BottomRight := ClientToScreen(R.BottomRight);
    FBalloonHint.Description := 'bad input';
    FBalloonHint.ShowHint(R);   //!!! Issue: No hint the first time around
  end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Edit1Exit(Sender);
end;

procedure TForm1.WMActivateApp(var AMessage: TMessage);
begin
  if Assigned(FBalloonHint) then FBalloonHint.HideHint;
  inherited;
end;

procedure TForm1.WMWindowPosChanged(var AMessage: TMessage);
begin
  if Assigned(FBalloonHint) then FBalloonHint.HideHint;
  inherited;
end;

      

+2


source







All Articles