Отображение подсказок - PullRequest
       42

Отображение подсказок

5 голосов
/ 07 декабря 2011

Я добавил подсказки к компонентам в моей форме.Когда компоненты получают фокус, я хочу установить заголовок компонента метки для отображения подсказки.

Я добавил объект TApplicationEvents и установил для события OnShowHint значение

procedure TImportFrm.ApplicationEvents1ShowHint(var HintStr: string;
  var CanShow: Boolean; var HintInfo: THintInfo);
begin
  HelpLbl.Caption := HintStr;
end;

Однако кажется, что событие ShowHint вызывается только движениями мыши.Есть ли способ запустить код подсказки, когда компоненты получают фокус, без необходимости реализовывать событие OnEnter для каждого компонента в форме?

Ответы [ 4 ]

4 голосов
/ 13 декабря 2011

Добавьте обработчик для TScreen.OnActiveControlChange при создании вашей основной формы и обработайте подсказки в этом событии:

type
  TForm2=class(TForm)
  ...
  private
    procedure ScreenFocusControlChange(Sender: TObject);
  end;

implementation

procedure TForm2.FormCreate(Sender: TObject);
begin
  Screen.OnActiveControlChange := ScreenFocusControlChange;
end;

procedure TForm2.ScreenFocusControlChange(Sender: TObject);
begin
  Label1.Caption := ActiveControl.Hint;
  Label1.Update;
end;

Обратите внимание, что Sender не принесет вам большой пользы;это всегда Screen.Вы можете отфильтровать (например, чтобы изменить Label.Caption только для элементов управления редактирования), протестировав ActiveControl:

if (ActiveControl is TEdit) then
  // Update caption of label with ActiveControl.Hint

Обратите внимание, что если вам потребуется переназначить событие при отображении дочерних форм(к событию в этой дочерней форме), или вы всегда будете обновлять метку оригинальной формы с помощью подсказок.Самый простой способ переназначения - дать каждой форме обработчик OnActiveControlChange, назначить его в событии OnActivate формы и отменить его в событии OnDeactivate:

procedure TForm1.FormActivate(Sender: TObject);
begin
  Screen.OnActiveControlChange := Self.ScreenActiveControlChange;
end;

procedure TForm1.FormDeactivate(Sender: TObject);
begin
  Screen.OnActiveControlChange := nil;
end;

Это позволитобновлять элементы управления, отличные от Label1, в каждой форме и использовать изменения подсказок только в тех формах, которые вы хотите сделать.

4 голосов
/ 13 декабря 2011

Простым решением является использование события OnIdle:

procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
  if Assigned(ActiveControl) then
    Label1.Caption:= ActiveControl.Hint;
end;

Более совершенным решением является переопределение защищенного ActiveChanged метода TForm:

type
  TForm1 = class(TForm)
    ...
  protected
    procedure ActiveChanged; override;
  end;

...

procedure TForm1.ActiveChanged;
begin
  inherited;
  if Assigned(ActiveControl) then
    Label1.Caption:= ActiveControl.Hint;
end;

Получениеfocus и OnShowHint - совершенно разные события;OnShowHint также может быть активировано для несфокусированного управления.

1 голос
/ 13 декабря 2011

Вы сказали:

кажется, что событие ShowHint происходит только при движениях мыши

Это нормальное поведение.Ваша проблема (это предположение) состоит в том, что подсказки не запускаются напрямую.Не пытайтесь обойти это, то, что вы пытаетесь сделать с помощью MouseEnter, это именно то, что уже происходит ... единственное отличие состоит в том, что вы что-то забудете ...

Сохраните событие ApplicationEvents1ShowHint ()как вы изначально сделали, но добавьте это в событие конструктора формы:

Application.HintPause := 1;

И тогда подсказки будут отображаться (почти) без задержки.

1 голос
/ 13 декабря 2011

Зачем вам нужно реализовывать событие OnEnter для каждого компонента? Вы можете создать один общий метод / обработчик событий, например:

procedure TForm1.AnyControlEnter(Sender: TObject);
begin
  lbl1.Caption := TControl(Sender).Hint;
end;

и назначьте его каждому компоненту, который вы поместили в форму.

...