AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Screen.OnActiveControlChange - gibt es Alternative?
Thema durchsuchen
Ansicht
Themen-Optionen

Screen.OnActiveControlChange - gibt es Alternative?

Ein Thema von taaktaak · begonnen am 16. Aug 2008 · letzter Beitrag vom 16. Aug 2008
Antwort Antwort
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.993 Beiträge
 
Delphi 7 Professional
 
#1

Screen.OnActiveControlChange - gibt es Alternative?

  Alt 16. Aug 2008, 15:44
Moin, Moin.
Ich hab eine Klasse, die Focuswechsel innerhalb meiner Anwendung verfolgt. Ziel ist es, insbesondere nach einem Klick auf einen Help-Button den Focus auf das vorher aktive Conrol zurücksetzen zu können. In diesem Thread hatte ich vor einiger Zeit einen ersten Lösungsversuch vorgestellt. Die damaligen von SirThornberry benannten Restriktionen konnten von mir leider nicht beseitigt werden.

Letztlich ist die Verwendung von Screen.OnActiveControlChange innerhalb der Klasse indiskutabel, da das Ganze nur funktioniert, wenn ich im übrigen Programmcode auf die Verwendung dieses Events verzichte. Als Notlösung ist im untenstehenden Code ein "eigenes" OnActiveControlChange enthalten, dass in der Anwendung anstelle des gleichnamigen Events von TScreen verwendet werden kann.

Das ist aber in meinen Augen keine vernünftige Lösung. Mein Ziel ist, die Nachricht über einen Focuswechsel ohne Verwendung von Screen.OnActiveControlChange zu erhalten und die Adresse des Controls zu speichern - und da komme ich nicht weiter.

Meine Versuche WM_SETFOCUS und WM_KILLFOCUS zu verwenden, scheiterten. Die Botschaften werden offenbar von der Klasse nicht empfangen. Dann fand ich CM_FOCUSCHANGED, eine, wenn ich das richtig verstanden habe, Delphi-interne Botschaft. Aber auch darauf reagierte meine Klasse nicht. Zuletzt habe ich versucht nachzuvollziehen, wie Delphi das Screen.OnActiveControlChange verwendet, aber auch das führte leider zu keinem Erfolg. Habe nicht feststellen können, ob Delphi hierzu überhaupt irgendwelche Windows-Botschaften verwendet; es scheint mir so, dass dieses Event von der VCL eigenständig ausgelöst wird.

Auch wenn's jetzt ein bisschen lang wird, hier mal der aktuelle Code:

Delphi-Quellcode:
unit rzM_WatchFocus;
//
// Application may NOT use Screen.OnActiveControlChange !!!
// Replacement >> WatchFocus.OnActiveControlChange !!!
//
// bad solution!!!!!!!!!!!
//
interface { ----------------------------------------------------------------- }

uses Classes,Controls,Forms;

type TWatchFocus = class(TControl)

                    private

                     FActiveControlChange : TNotifyEvent;

                     FActControl,
                     FLastControl,
                     FStoreControl : TWinControl;

                     procedure CollectFocus (Sender:TObject);

                    public

                     procedure StoreLastFocus;
                     procedure RestoreLastFocus;
                     property OnActiveControlChange : TNotifyEvent
                                                         read FActiveControlChange
                                                         write FActiveControlChange;

                     constructor Create (AOwner:TComponent); override;
                     destructor Destroy; override;

                    end;

var WatchFocus : TWatchFocus;

implementation { ------------------------------------------------------------ }

procedure TWatchFocus.CollectFocus(Sender:TObject);
begin
  if Assigned(FActiveControlChange) then FActiveControlChange(Self);
  FLastControl:=FActControl;
  FActControl :=Screen.ActiveControl;
end;

procedure TWatchFocus.StoreLastFocus;
begin
  if FLastControl<>nil then FStoreControl:=FLastControl;
end;

procedure TWatchFocus.RestoreLastFocus;
begin
  if FStoreControl<>nil then
    if FStoreControl.Visible then
      if FStoreControl.Enabled then FStoreControl.SetFocus;
end;

constructor TWatchFocus.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  FActControl :=nil;
  FLastControl :=nil;
  FStoreControl:=nil;
  Screen.OnActiveControlChange:=CollectFocus
end;

destructor TWatchFocus.Destroy;
begin
  Screen.OnActiveControlChange:=nil;
  inherited Destroy
end;

initialization { ------------------------------------------------------------ }

  WatchFocus:=TWatchFocus.Create(nil);

finalization { -------------------------------------------------------------- }

  WatchFocus.Free;
  WatchFocus:=nil;

end.
Die Klasse wird nur mir uses eingebunden und z.B. so verwendet:

Delphi-Quellcode:
procedure TfoImportScan.buHelpClick(Sender:TObject);
begin
  WatchFocus.StoreLastFocus;
  // call help
  WatchFocus.RestoreLastFocus;
end;
Tja, da stehe ich nun ratlos an der Grenze meiner Kenntnisse und hoffe auf eure Hilfe...
Ralph
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Screen.OnActiveControlChange - gibt es Alternative?

  Alt 16. Aug 2008, 18:51
Hier mal ein Vorschlag...

Edit: Wichtig, habe noch etwas verändert!
Angehängte Dateien
Dateityp: zip watchfocus_186.zip (2,9 KB, 22x aufgerufen)
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.993 Beiträge
 
Delphi 7 Professional
 
#3

Re: Screen.OnActiveControlChange - gibt es Alternative?

  Alt 16. Aug 2008, 19:06
Aaaaaaaaaaha

könntest du mir den Code mal im "Venezia" erklären???
(Bist eingeladen)
Ralph
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Screen.OnActiveControlChange - gibt es Alternative?

  Alt 16. Aug 2008, 19:10
Was ist daran unverständlich?
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.993 Beiträge
 
Delphi 7 Professional
 
#5

Re: Screen.OnActiveControlChange - gibt es Alternative?

  Alt 16. Aug 2008, 19:15
Nach kurzem draufschauen so ziemlich alles. Aber zunächst einmal vielen Dank für deinen Aufwand. Ich werde es mir mal in Ruhe anschauen

// edit
Nach erstem Versuch den Code zu verstehen, mit den Worten eines Stümpers:
Der Thread nutzt auch Screen.ActiveControlChange und "verbiegt" das Event regelmäßig auf TWatchFocus. Sobald das Ergebnis übergeben ist, wird das Event wieder "zurückgebogen". Nun, auf jeden Fall ist es mir gelungen eine Prozedur "RestoreLastFocus" einzubauen und damit meine (aktuelle) Aufgabenstellung zu befriedigen. Die weitergehenden Möglichkeiten der History können später genutzt werden. Bis dahin genügt es mir, das ganze als "Blackbox" zu nutzen.

// edit2
Damit die Liste nicht irgendwann mal überläuft habe ich der Unit nun noch eine festlegbare Obergrenze der Listengröße spendiert.

omata - noch einmal meinen herzlichen Dank!
Ralph
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz