I'm following this example: http://lawrencebarsanti.wordpress.com/2009/12/16/display-error-messages-with-tballoonhint/
I'm trying to only show a balloon hint when the current value in the edit box is not acceptable. The check is triggered when OnExit
. The balloon should still be allowed to display until the value is determined to be OK. I'm also trying to programmatically show the balloon as soon as the user leaves the edit to show the initial error.
The code works, but not the first time. I have to leave once with an invalid value, change to an acceptable one, then come back and use an invalid one again. I think this is because I can't enable or disable the ShowHint property right before I try 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 right when I check for a valid value (leaving the edit)?
Actually, the thing that's odd is that you get anything the second time, not that you don't get anything the first.
Your code works for me (in XE4 & XE6) 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 did work for you second time around, I think it's because of code you're not showing, and equally something you're not showing is probably why it doesn't work the first. So you can "spot the difference", the code of my project is below. I couldn't find your StrIsReal function so rolled my own.
Btw, I added a second TEdit to my form, so that there is something else on it to lose focus to, and commented out your two Edit1.ShowHint assignments as they don't make any difference but shouldn't be necessary 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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With