![]() |
Restore last focus
Moin, Moin,
normalerweise ist es wohl uninteressant, welches Control zuletzt den Focus hatte. Für mich gibt es da aber eine Ausnahme: Rufe ich in meinem Programm mit einem Button die Hilfe auf, möchte ich nach Schliessen des Hilfefensters den Focus wieder auf dem zuletzt benutzten Control haben - und nicht auf dem Help-Button. Bisher habe ich das immer recht aufwendig in jedem relevanten Formular lokal programmiert. Blöde Lösung! Heute Abend hatte ich dann eine Idee, die ich dann in folgender Mini-Klasse umgesetzt habe:
Delphi-Quellcode:
Die Anwendung ist denkbar einfach; die Klasse wird lediglich per USES eingebunden. Damit steht dann die Prozedur "RestoreFocus" zur Verfügung. Anwendungsbeispiel:
unit rzM_WatchFocus;
interface { ----------------------------------------------------------------- } uses Wintypes,Classes,Controls,Forms; type TWatchFocus = class(TComponent) private FActControl, FLastControl : TWinControl; procedure SaveFocus (Sender:TObject); public procedure RestoreFocus; constructor Create (AOwner:TComponent); override; destructor Destroy; override; end; var WatchFocus : TWatchFocus; implementation { ------------------------------------------------------------ } procedure TWatchFocus.SaveFocus(Sender:TObject); begin if FActControl=nil then FActControl:=Screen.ActiveControl else begin FLastControl:=FActControl; FActControl :=Screen.ActiveControl end end; procedure TWatchFocus.RestoreFocus; begin if FLastControl<>nil then FLastControl.SetFocus end; constructor TWatchFocus.Create(AOwner:TComponent); begin inherited Create(AOwner); FActControl :=nil; FLastControl:=nil; Screen.OnActiveControlChange:=SaveFocus end; destructor TWatchFocus.Destroy; begin Screen.OnActiveControlChange:=nil; inherited Destroy end; initialization { ------------------------------------------------------------ } WatchFocus:=TWatchFocus.Create(nil); finalization { -------------------------------------------------------------- } WatchFocus.Free; WatchFocus:=nil; end.
Delphi-Quellcode:
Bislang funktioniert das wie gewünscht. Habe ich da mal wieder zu aufwendig gedacht, da Delphi diese Funktionalität schon bietet und ich das nur nicht gefunden habe?
procedure TfoConfig.buHelpClick(Sender:TObject);
begin case PageControl.ActivePageIndex of 0 : Application.HelpJump('ConfigStartup'); 1 : Application.HelpJump('ConfigColorAlphablend'); end; WatchFocus.RestoreFocus // << Focus wieder auf letztes Control vor HelpButton setzen end; PS: Kann mir bitte mal einer erklären, wieso TWatchFocus.Create(nil) mit NIL erfolgen muss (hatte erst Self probiert, funktionierte aber nicht) |
Re: Restore last focus
Zitat:
An sich ist das ganze eine ganz nette Idee aber ein paar Kritikpunkte/Verbessungspunkte hab ich. Was mir an deiner Klasse nicht gefällt ist das sie das Screen.OnActiveControlChange nutzt. Wenn dieses Event bereits in Verwendung ist wird es einfach umgesetzt was nicht sonderlich schön ist. Wenn es unbedingt das Event sein soll wäre es schön wenn du prüfst ob bereits eine Methode zugewiesen ist und diese dann gegebenfalls von deinem Event aus aufrufst. Beim Zerstören dann natürlich auch schauen ob dem Event noch deine Methode zugewiesen ist und nur dann das Event auch wieder zurück setzen. Wenn die Komponente universell nutzbar sein soll wäre es auch schön wenn du eine History führst die nicht nur das letzte Control kennt sondern einige zuvor auch noch. Zusetzlich solltest du auch sicherstellen das dieses Control (fLastControl) auch noch existiert und nicht in der Zwischenzeit frei gegeben wurde. Dann würde dein fLastControl ins Nirvana zeigen und es kracht. Aber wie bereits erwähnt, die Idee an sich ist nicht schlecht. |
Re: Restore last focus
Moin, Moin,
vielen Dank für die Anmerkungen, werde das kurzfristig (versuchen) einzubauen. Es kracht leider auch noch an anderer Stelle, wie ich eben (wie immer so kurz vor dem Aussschalten des PC) feststellen musste: Nach einem Fensterwechsel wird gemeckert "Ein deaktiviertes oder unsichtbares Fenster kann nicht den Fokus erhalten" - Na, da muss doch noch einmal gefeilt werden... angefügter Beitrag: Moin, Moin, die Verwendung von Screen.OnActiveControlChange ist wohl tatsächlich der falsche Ansatz! Klasse und Anwendungsprogramm können sich gegenseitig die Events "klauen". In der Klasse könnte man das noch abfangen, aber wenn das auch im Anwendungsprogramm erfolgen muss, ist die Bequemlichkeit wieder futsch! Habe jetzt 'ne Weile den direkten Ansatz (also Windows-Messages) ohne wirkliche Ergebnisse versucht, muss aber aus Zeitmangel dieses Thema erst einmal abbrechen. Für die angesprochene Fokus-Historie könnte man vielleicht einen Ringpuffer verwenden. Aber, wie gesagt, muss auf später verschoben werden. :( [edit=SirThornberry]Beiträge zusammengeführt - Mfg, SirThornberry[/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz