Tonen weergeven

Ik heb hints toegevoegd aan onderdelen op mijn formulier. Wanneer de componenten de focus krijgen, wil ik het bijschrift van een labelcomponent instellen om de hint weer te geven.

Ik heb een object TApplicationEvents toegevoegd en de gebeurtenis OnShowHint ingesteld op

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

Het lijkt er echter op dat de ShowHint-gebeurtenis alleen met muisbewegingen vuurt. Is er een manier om de hintcode af te vuren wanneer componenten focus ontvangen, zonder de OnEnter-gebeurtenis te hoeven implementeren voor elk onderdeel op het formulier?

5
Ik gebruik de VCL en XE2.
toegevoegd de auteur Sam M, de bron
Wat gebruikt u, VCL of FMX?
toegevoegd de auteur Kromster, de bron

4 antwoord

Voeg een handler toe voor TScreen.OnActiveControlChange in de aanmaak van uw hoofdformulier en behandel de hints in dat geval:

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;

Merk op dat Afzender u niet veel goed zal doen; het is altijd Scherm . U kunt filteren (bijvoorbeeld om alleen de Label.Caption te wijzigen voor bewerkingsbesturingselementen) door de ActiveControl te testen:

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

Houd er rekening mee dat als u de gebeurtenis opnieuw moet toewijzen wanneer u onderliggende formulieren weergeeft (aan een gebeurtenis op dat onderliggende formulier), of u altijd het label van het originele formulier bijwerkt met de hints. De eenvoudigste manier om de toewijzing uit te voeren, is om elke vorm een ​​ OnActiveControlChange -handler te geven en deze toe te wijzen aan de gebeurtenis OnActivate van het formulier en deze ongedaan te maken in de OnDeactivate evenement:

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

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

Hiermee kunt u andere besturingselementen dan Label1 bijwerken op elk formulier en alleen de hintwijzigingen gebruiken op formulieren die u wilt gebruiken.

4
toegevoegd
Bedankt Ken. Die gebeurtenis is precies wat ik zocht, ik vergat gewoon om buiten het TForm-object te kijken.
toegevoegd de auteur Sam M, de bron

Een eenvoudige oplossing is om OnIdle -gebeurtenis te gebruiken:

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

Een geavanceerdere oplossing is om de beschermde ActiveChanged -methode van TForm te overschrijven:

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

...

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

Het ontvangen van focus en OnShowHint zijn behoorlijk verschillende gebeurtenissen; OnShowHint kan ook worden geactiveerd voor niet-gerichte besturing.

4
toegevoegd
+1 Voor gebruik van OnIdle. Een suggestie: gebruik eerder Screen.ActiveControl dan (Self) .ActiveControl om het breed te laten werken; niet alleen voor TForm1, maar ook voor mogelijke pop-upvormen en dergelijke.
toegevoegd de auteur NGLN, de bron
Dit is dezelfde methode die ik gebruik in mijn TKinect "Virtual Mouse Cursor" demo ... werkt goed! 1
toegevoegd de auteur LaKraven, de bron

Jij zei:

het lijkt erop dat de ShowHint-gebeurtenis alleen met muisbewegingen wordt afgevuurd

Dit is een normaal gedrag. Het probleem dat je hebt (het is een gok) is dat hints niet direct worden geactiveerd. Probeer geen oplossing te maken, wat u probeert te doen met MouseEnter is precies wat er al gebeurt ... het enige verschil is dat u iets bent vergeten ...

Houd de gebeurtenis ApplicationEvents1ShowHint() zoals je aanvankelijk hebt gedaan, maar voeg deze toe in de formulierconstructorgebeurtenis:

Application.HintPause := 1;

En vervolgens worden hints (vrijwel) onverwijld weergegeven.

1
toegevoegd

Waarom zou u de OnEnter -gebeurtenis voor elk onderdeel moeten implementeren? U kunt één generieke methode/gebeurtenishandler maken, zoals:

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

en wijs het toe aan elk onderdeel dat u op het formulier hebt geplaatst.

1
toegevoegd