Flexible method of detecting focused control change

cognitive flexibility examples
cognitive flexibility test
cognitive flexibility executive function
cognitive flexibility exercises
cognitive flexibility assessment
cognitive flexibility in the workplace
cognitive flexibility pdf
cognitive flexibility and control

I need to write a component which will register in self other components and will detect if one of the registered components receive focus.

For example for my component TFocusObserver I am registering three objects.

FocusObserver.Register(MyMemo);
FocusObserver.Register(MyButton);
FocusObserver.Register(MyEdit);

And now if one of this components receives focus then FocusObserver is firing up some notification event.

I was looking how to detect a focus change and have found that TScreen.OnActiveControlChange is exactly what I need. So my component could hook up to this event. The problem is that more than one TFocusObserver might exists or later in a future somoene else might want to use OnActiveControlChange.

This is the time in which I would benefit from multicast event - it would solve my problem right away.

I was thinking how to solve this and I have currently two ideas:

  1. Extending somehow TScreen so it would provide one more event for me.
  2. Introduce an intermediate object which will hook up to OnActiveControlChange and expose one multicast event for other objects.

After a brief look at the sources I have no clear idea how to solve it by using first idea and the second idea has the drawback that someone can simply assign another method to OnActiveControlChange and everything fill fall apart.

Will be grateful for some suggestions.

If your focusObserver class can be a descendant of TWinControl, than you can do this:

TFocusObserver = class( TWinControl )

  procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
end;

and

procedure TFocusObserver.CMFocusChanged(var Message: TCMFocusChanged);
var
  LControl: TWinControl;

begin
      LControl := TWinControl(Message.Sender);

      if LControl <> nil then
      begin
        form1.Caption := lControl.Name;
      end;
end;

Here the main idea is to watch CM_FOCUSCHANGED.

Second approach:

When registering the Control you replace it's WindowProc. Here's a little code snippet:

TRegisteredComp = class
  private
    fControl: TControl;
    fowndproc: TWndMethod;
    procedure HookWndProc(var Message: TMessage);
  public
    constructor Create( c: TControl );
    destructor Destroy; override;
  end;

  TFocusObserver = class
  private
    l: TList;
   public
    constructor Create;
    destructor Destroy; override;
    procedure reg( c: TControl );

  end;

and under implementation:

constructor TFocusObserver.Create;
begin
  l := TList.Create;
end;

destructor TFocusObserver.Destroy;
var i: integer;
begin
  for i := 0 to l.Count - 1 do
    TRegisteredComp(l[i]).Free;
  l.Free;
  inherited;
end;

procedure TFocusObserver.reg( c: TControl );
var
  rc: TRegisteredComp;
begin
  rc := TRegisteredComp.Create( c );
  l.Add( rc );
end;

constructor TRegisteredComp.Create(c: TControl);
begin
  fControl := c;
  fowndproc := c.WindowProc;
  c.WindowProc := HookWndProc;
end;

destructor TRegisteredComp.Destroy;
begin
  fControl.WindowProc := fowndproc;
  inherited;
end;

procedure TRegisteredComp.HookWndProc(var Message: TMessage);
begin
  if ( Message.Msg = CM_FOCUSCHANGED ) and
    ( TControl(Message.LParam) = fControl ) then
    form1.ListBox1.Items.Add( 'focused: ' + fControl.Name );

  fowndproc( Message );
end;

than just register the control you want to watch, example:

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  fo := TFocusObserver.Create;
  for i := 0 to ControlCount - 1 do
    fo.reg( Controls[i] );
end;

How does it sound?

delphi, i looking how detect focus change , have found tscreen.onactivecontrolchange need. component hook event. problem more 1 tfocusobserver  However, there is a little known Protected method that has existed in Container Controls (a form is a container control) since .NET 2.0 that is called UpdateDefaultButton. This method is called whenever a containercontrol 's ActiveControl property changes. This change typically is the result of either a mouse or keyboard action,

You could remember the value of Screen.OnActiveControlChange just before your component replaces it.

FOnActiveControlChange := Screen.OnActiveControlChange;
Screen.OnActiveControlChange = MyOnActiveControlChange;

Then in xxx.MyOnActiveControlChange

begin
  // what you wanted to do here
  ...

  if Assigned( FOnActiveControlChange) then begin

    // Forward to previous subscriber.
    FOnActiveControlChange( Sender, ...);
end;

But this only works if you're in control of the application, if someone else uses your component and he/she has other components that also use OnActiveControlChange things might go wrong.

Flexible method of detecting focused control change, I was looking how to detect a focus change and have found that TScreen.​OnActiveControlChange is exactly what I need. So my component could hook up to this  In this respect, the invention concerns a Method of detecting, locating and/or analyzing a radioactive source(s) emitting charged or neutral particles in a material, particularly a biological tissue, consisting essentially in using scintillating fiber(s) having a ratio L (Length)/r (range of the particles emitted by the source)≧2, d (diameter

I know this is a very old post but here it is :

If using a third party library is an option, you could always use Spring4d

I implemented something similar in the past. It goes in the lines of :

uses

Spring;

type

TActiveControl = class(TObject)
private
   FEvent : Event<TNotifyEvent>;
   class var FInstance : TActiveControl;
   function GetOnActiveControlChanged : IEvent<TNotifyEvent>;
   procedure DoOnActiveControlChanged(Sender : TObject);
public
   class property Instance : TActiveControl read FActiveControl;
   property OnActiveControlChanged : IEvent<TNotifyEvent> get GetOnActiveControlChanged;
   constructor Create;
   destructor Destroy; override;
end;

TSubscriber = class(TObject)
private
   procedure DoOnActiveControlChanged(Sender : TObject);
public
   constructor Create;
   destructor Destroy; override;
end;

...

function TActiveControl.GetOnActiveControlChanged : IEvent<TNotifyEvent>
begin
  Result := FEvent;
end;

constructor TActiveControl.Create
begin
  Screen.OnActiveControlChanged := DoOnActiveControlChanged;
end;

destructor TActiveControl.Destroy;
begin
   OnActiveControlChanged.Clear;
   FOnActiveControlChanged := nil;
   inherited;
end;

procedure TActiveControl.DoOnActiveControlChanged(Sender : TObject);
begin
  if OnActiveControlChanged.CanInvoke
     OnActiveControlChanged.Invoke(Sender);
end;

procedure TSubscriber .DoOnActiveControlChanged(Sender : TObject);
begin
   // OnActiveControl has been triggered
end;


constructor TSubscriber.Create;
begin
   TActiveControl.Instance.OnActiveControlChanged.Add(DoOnActiveControlChanged); 
end;


destructor TSubscriber .Destroy


initialization

   TActiveControl.FInstance := TActiveControl.Create;

finalization

   FreeAndNil(TActiveControl.FInstance);

In this case I use a simple version of the singleton pattern for TActiveControl. You could also create an interface for it (IActiveControl) and inject it when necessary using IOC. This is a further step though.

This way, all your calls to Screen.OnActiveControlChanged should instead use TActiveControl.Instance.OnActiveControlChanged. Spring4d is awesome. There's lots of stuff in it, including multicast, IOC container, collections, etc. etc.

Applied Mechanics Reviews, In this paper, a robust motion control method for kinematically redundant 11A461. Model-free controller design for a single-link flexible smart materials robot. With the special motion feature of the on-board camera and its Focus of Expansion, our method can detect the real moving objects from the continuously changing  We developed rMATS, a new statistical method for robust and flexible detection of differential AS from replicate RNA-Seq data. Besides the analysis of unpaired replicates, rMATS includes a model specifically designed for paired replicates, such as case–control matched pairs in clinical RNA-Seq datasets.

Official Gazette of the United States Patent and Trademark Office: , 4,626,679 OPTICAL HEAD AND METHOD OF DETECTING THE FOCUS source unit and said detecting unit, and including a transparent block; and a flexible the diaphragm and the optical system is a focusing system which can change the 4,626,681 DIFFERENTIAL PRESSURE CONTROL APPARATUS Thomas E. Make use of the tag property (All control's have this property including the form) .You can store the currently focused controls name in the Tag property.Something like this. btnCall.Tag = txtNotes; When you are back to the form,check for tag property which you have set & bring back the focus on that control. Posted 9-Jan-11 7:25am.

Femtosecond Laser Micromachining: Photonic and Microfluidic , Dynamic control of the spatial phase can efficiently respond to expectations and aspects determine the resulting path for the refractive index change. be presented in Sect.4.3, with a focus on Fourier synthesis of light components. An overview on the achieved spatio-temporal flexibility in irradiation, the detection method,  This method can be used both invivo and invitro4,5.In this method the teeth are isolated with a latex isolator i.e. the clinical crown was isolated and 2ml of manganese (non – radioactive ) was injected into the flexible latex bag for a soaking period of one hour.

Control, Computers, Communications in Transportation: Selected , A FLEXIBLE TOOL FOR RAILWAY REGULATION The approach and the Moreover, propagating constraints enables the detection of £ences between the work of the designer or operator to configure a new line or to access and modify data. individual train viewpoints (e.g. regulation can focus on the local relationships  25. Identify the true statement about detecting fraud using financial statement reports. a. Performing horizontal analysis requires converting the Income statement balances to percentages of gross sales. b. Vertical analysis is the most direct method of focusing on changes from period to period. c.

Comments
  • If you said more than one TFocusObserver might exists at one time I guess, did you mean that all of them should have get notified about those focus changes or only one of them ?
  • What is the base class of TFocusObserver?
  • Thanks, this solution has two drawbacks: 1 - I must place this component on a form so it could capture change of focus. 2- It will detect the focus change only on the form on which it sits. However, if nothing better comes up I'll accept this as an answer.
  • I appreciate your time and the second approach works for me. Thanks.
  • Thanks Marck, as I stated in my question - someone else might change assignment for TScreen.OnActiveControlChange. So this won't work...
  • Well, another option is to listen for CM_FOCUSCHANGED messages.