以编程方式显示Balloon Hint仅用于无效的文本编辑输入

ika*_*eat 6 delphi hint

我正在效仿这个例子:http: //lawrencebarsanti.wordpress.com/2009/12/16/display-error-messages-with-tballoonhint/

我正在尝试仅在编辑框中的当前值不可接受时显示气球提示.检查是在触发时触发的OnExit.仍应允许显示气球,直到确定该值为止.我还尝试在用户离开编辑时以编程方式显示气球以显示初始错误.

代码有效,但不是第一次.我必须使用无效值离开一次,更改为可接受的值,然后再次使用无效值.我想这是因为我在尝试显示气球之前无法启用或禁用ShowHint属性.

这是我的代码:

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;
Run Code Online (Sandbox Code Playgroud)

当我检查有效值(离开编辑)时,如何有条件地显示气球?

Mar*_*ynA 6

事实上,奇怪的是你第二次得到了任何东西,而不是你第一次没有得到任何东西。

通过以下更改,您的代码第一次(和第二次)对我(在 XE4 和 XE6 中)有效:

  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
Run Code Online (Sandbox Code Playgroud)

所以,如果它第二次对你有用,我认为这是因为你没有显示代码,同样你没有显示的东西可能就是它第一次不起作用的原因。所以你可以“发现差异”,我的项目的代码如下。我找不到你的 StrIsReal 函数,所以我自己推出了。

顺便说一句,我在表单中添加了第二个 TEdit,以便它上面有其他东西可以失去焦点,并注释掉您的两个 Edit1.ShowHint 分配,因为它们没有任何区别,但无论如何都不应该是必要的。

  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;
Run Code Online (Sandbox Code Playgroud)