2011-12-06 16 views
5

Dodałem podpowiedzi do komponentów w moim formularzu. Gdy komponenty są skupione, chciałbym ustawić podpis składnika etykiety, aby wyświetlić wskazówkę.Wyświetlane podpowiedzi

Dodałem TApplicationEvents obiekt i ustawić OnShowHint zdarzenie

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

Jednak wydaje się, że zdarzenie ShowHint tylko pożary z ruchami myszy. Czy istnieje sposób na wystrzelenie kodu podpowiedzi, gdy komponenty otrzymują fokus, bez konieczności implementowania zdarzenia OnEnter dla każdego komponentu w formularzu?

+0

Czego używasz, VCL lub FMX? – Kromster

+0

Używam VCL i XE2. –

Odpowiedz

4

Dodawanie obsługi dla TScreen.OnActiveControlChange w tworzeniu głównego formularza, a uchwyt podpowiedzi w takim przypadku:

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; 

Zauważ, że Sender nie będzie Pan wiele dobrego; zawsze jest to Screen. Strefy czasowe (na przykład, aby zmienić tylko Label.Caption do edycji kontroli) poprzez testowanie ActiveControl:

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

pamiętać, że jeśli trzeba przypisać zdarzenie kiedy pokażesz form potomnych (na razie na tym forma dziecka), lub zawsze będziesz aktualizować etykietę oryginalnego formularza z podpowiedziami. Najprostszym sposobem, aby zrobić zmiany przeznaczenia jest dać każdemu tworzyć OnActiveControlChange obsługi i przypisać go w formie za OnActivate imprezy i cofnąć ją w razie OnDeactivate:

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

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

pozwoli na aktualizację kontrole inne niż Label1 na w każdym formularzu i używaj tylko zmian podpowiedzi w formularzach, które chcesz.

+0

Dzięki Ken. To wydarzenie jest dokładnie tym, czego szukałem, po prostu zapomniałem wyjść poza obiekt TForm. –

4

Prostym rozwiązaniem jest użycie OnIdle zdarzenie:

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

Bardziej zaawansowanym rozwiązaniem jest nadpisanie chroniony ActiveChanged metoda TForm:

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

... 

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

Odbieranie ostrość i OnShowHint są zupełnie różne wydarzenia; OnShowHint może być również wyzwalany dla sterowania nieskonfigurowanego.

+1

+1 Do używania OnIdle. Sugestia: użyj Screen.ActiveControl zamiast tego (Self) .ActiveControl, aby uzyskać działającą aplikację szeroko; nie tylko dla TForm1, ale także dla możliwych wyskakujących formularzy i tym podobnych. – NGLN

+0

To jest ta sama metoda, której używam w mojej demonstracji "Virtual Mouse Cursor" TKinect ... działa dobrze! +1 – LaKraven

1

Dlaczego konieczne jest wdrożenie zdarzenia OnEnter dla każdego komponentu? Można utworzyć jedną ogólną procedurę obsługi zdarzeń lub zdarzenia, taką jak:

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

i przypisać ją do każdego komponentu umieszczonego w formularzu.

1

Mówiłeś:

wydaje się, że zdarzenie ShowHint odpala tylko z ruchów myszy

Jest to normalne zachowanie. Problemem jest to, że podpowiedzi nie są uruchamiane bezpośrednio. Nie próbuj obejść tego problemu, to, co próbujesz zrobić z MouseEnter, jest dokładnie tym, co już się dzieje ... jedyna różnica polega na tym, że zapomnisz czegoś ...

przechowywać zdarzenie ApplicationEvents1ShowHint() jak masz zrobić, ale początkowo dodać to w przypadku formularza Konstruktor:

Application.HintPause := 1; 

A potem będą wyświetlane podpowiedzi (prawie) bez zwłoki.