Einzelnen Beitrag anzeigen

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