finding out why onExit occurs

I need something "behind-the-scenes" probably. I have a form with a lot of visual components. Among these components are tedits and tbitbtns. What I want to do is, inside an onExit event handler, to determine why the tedit is loosing focus, is it because the user pressed the tab/enter key (and if so which key did he/she press), did he/she click on another component with the mouse, or did he/she use an accelerator key (and if so, what combination of accelerator keys).  This should be accomplished without having to react to every single keypress, mouseup etc for all components and the form itself.

In a perfect world there would be a call like GetLastUserAction or something, but... :-)
hatecaplettersAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

intheCommented:
listening ..
0
rwilson032697Commented:
Listening
0
EpsylonCommented:
I can't think of a way to do this without using OnKeyPress etc...
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

rwilson032697Commented:
You can use TScreen.OnActiveControlChange to track whenever focus changes to another control. This gives a useful way of tracking this kind of activity in a general fashion (not quite what you ae looking for though...)

Cheers,

Raymond.
0
brunoheCommented:
One solution might be to catch all WM_KEYDOWN and WM_LBUTTONDOWN messages on the form, register them in a list and dispatch them to the controls.

Then, when he exits the TEdit-Control, you can look in the list what he did last. The problem ist, that EVERY key and mouse-down ist registered in the list...

This would be the easiest, imho.
0
RadlerCommented:
I be happy at help you, A friend ask me this at past and solve it with this:

unit LstCtrl;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TLastControlForm = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
       { Private declarations }
  protected
      FLastFocusControl : TControl;
      procedure WndProc(var Message: TMessage); override;
  public
       { Public declarations }
       property LastFocusControl : TControl read FLastFocusControl;
  end;

var
  LastControlForm: TLastControlForm;

implementation

{$R *.DFM}

procedure TLastControlForm.FormCreate(Sender: TObject);
begin
      FLastFocusControl:=Self.ActiveControl;
end;

procedure TLastControlForm.WndProc(var Message: TMessage);
begin
      //if Self.Active then begin
            case Message.Msg of
                  CM_FOCUSCHANGED : begin
                        if Self.LastFocusControl <> Self.ActiveControl then begin
                              FLastFocusControl:=Self.ActiveControl;
                        end;
                  end;
            end;
      //end;
      inherited WndProc(Message);
end;

end.


T++, Radler.
0
brunoheCommented:
Radler, that's not exactly what hatecapletter needs...
0
RadlerCommented:
Oops, really :o( , is incomplete.
Let's go finish the answer.
at now the first step:
** The focus changes reason **
1 - Create a var to hold the last event type( Mouse/Kbd ) to identify the reason of Focus changes.
2 - At the WndProc update this var like this

Case Message.Msg of
WM_MOUSEFIRST, WM_MOUSELAST : begin
  var:='Mouse event'
end;
WM_KEYFIRST, WM_KEYLAST : begin
  var:='Kbd event'
  var2:=Message.wparam; //Catch the lastkey pressed
end;

The final affinaments after hatecapletters pronuonces.

T++, Radler.
0
brunoheCommented:
When I'm looking in the MSDN, WM_KEYFIRST and WM_KEYLAST are only on Windows CE. What the hell do WM_MOUSEFIRST and WM_MOUSELAST?
0
RadlerCommented:
Hi brunohe( Brazilian too ? ), I'm from Recife.
You are welcomed at E-E.
I'm a bit buzy now, so a short answer to a question that isn't your.

You'll find at messages unit

  WM_MOUSEFIRST       = $0200;
  WM_KEYFIRST         = $0100;
  WM_KEYLAST          = $0108;
  WM_MOUSELAST        = $020A;

The answer is going at the rigth way, but some details sholud be determinated by hatecapletters( what it's meaning ? ).

T++, Radler.
0
hatecaplettersAuthor Commented:
well, I think we are on the right track, but...
 I don't seem to be able to catch what key was pressed to trigger the onExit. Specifically  i need to know if the user pressed the TAB key, the ENTER key, used a hot-key from my menu, or used an accelerator key on one of the buttons.  Keep those ideas coming :-)
0
geobulCommented:
Hi,

I have a proposal:

Your app needs to remember the last user action before a control can read this information on OnExit event.

The idea is to use Application.OnMessage event to record user actions in a global app variable.

1. Create a new unit named MyTools

unit MyTools;
interface
uses Classes;
type
  { This type is used to store last user action }
  TUserAction = record
    Key         : Word;
    Shift       : TShiftState;
  end;
var
  LastUserAction : TUserAction;
implementation
initialization
  LastUserAction.Key := 0;
  LastUserAction.Shift := [];
end.

2.In app main form write function AppOnMessage and associate it with Application OnMessage event.

uses .... ,MyTools;
type
  TMainForm = class(TForm)
    ...
    procedure FormCreate(Sender: TObject);
    procedure AppOnMessage(var Msg: TMsg; var Handled: Boolean);
    ...

implementation

{$R *.DFM}

procedure TMainForm.AppOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
  { if keyboard or left mouse btn is used }
  if (Msg.Message = WM_LBUTTONDOWN) or (Msg.Message = WM_KEYDOWN) then begin
    { record mouse left button }
    if (Msg.Message = WM_LBUTTONDOWN) then begin
      LastUserAction.Shift := [ssLeft];
      LastUserAction.Key   := 0;
    end;
    { record key action }
    if (Msg.Message = WM_KEYDOWN) then begin
      LastUserAction.Shift := [];
      {if the Shift key pressed}
      if ((Msg.lParam AND (1 shl 29)) <> 0) then
        LastUserAction.Shift := LastUserAction.Shift + [ssAlt];
      {if the Control key pressed}
      if ((GetKeyState(VK_CONTROL) AND (1 shl 15)) <> 0) then
        LastUserAction.Shift := LastUserAction.Shift + [ssCtrl];
      {if the Shift key pressed}
      if ((GetKeyState(VK_SHIFT) AND (1 shl 15)) <> 0) then
        LastUserAction.Shift := LastUserAction.Shift + [ssShift];
      LastUserAction.Key := Msg.wParam;
    end;
  end;
  Handled := False;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppOnMessage;
end;

3. And use information stored in LastUserAction variable in OnExit event of any control in any form of your app. Remember 'uses ... ,MyTools;' in forms.

procedure TMainForm.Edit1Exit(Sender: TObject);
begin
  { label1 shows key code
    label2 shows string 'Mouse' or 'Keyboard'
    label3 shows Alt,Shift,Control }
  Label1.Caption := IntToStr(LastUserAction.Key);
  if (ssLeft in LastUserAction.Shift) then
    Label2.Caption := 'Mouse'
  else
    Label2.Caption := 'Keyboard';
    if (ssShift in LastUserAction.Shift) then
      Label3.Caption := 'Shift';
    if (ssAlt in LastUserAction.Shift) then
      Label3.Caption := Label3.Caption + ' Alt';
    if (ssCtrl in LastUserAction.Shift) then
      Label3.Caption := Label3.Caption + ' Control';
end;

Good luck and
Regards, Geo
0
RadlerCommented:
Hi hatecapletters

I'm in transit I found a more complete solution with a little bug to detect the ALT key, When back the final solution will be send.
By momment take this. I'll be happy in have a A glade to this question, So wait by my final solution( code ).
Let's go:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;


type
  TOnControlFocus = procedure( Sender : TObject; IsMouse : boolean; ShiftState : TShiftState) of object;
  TLastControlForm = class(TForm)
       Edit1: TEdit;
       Edit2: TEdit;
       Edit3: TEdit;
       Edit4: TEdit;
       BitBtn1: TBitBtn;
       BitBtn2: TBitBtn;
       BitBtn3: TBitBtn;
       BitBtn4: TBitBtn;
       ReasonLbl: TLabel;
       KeyLbl: TLabel;
       Label1: TLabel;
       procedure FormCreate(Sender: TObject);
  private
    IsMouse : boolean;
       FOnControlFocus: TOnControlFocus;
       procedure SetOnControlFocus(const Value: TOnControlFocus);
       { Private declarations }
  protected
      FLastFocusControl : TControl;
      procedure WndProc(var Message: TMessage); override;
      procedure MyProc( Sender : TObject; IsMouse : boolean; ShiftState : TShiftState);
  public
       { Public declarations }
       property LastFocusControl : TControl read FLastFocusControl;
       property OnControlFocus : TOnControlFocus read FOnControlFocus write SetOnControlFocus;
  end;

var
  LastControlForm: TLastControlForm;

implementation

{$R *.DFM}

procedure TLastControlForm.FormCreate(Sender: TObject);
{-------------------------------------------------------------------------------------------------------------}
begin
      FLastFocusControl:=Self.ActiveControl;
      Self.OnControlFocus:=Self.MyProc; //Force to this example only OK ?
end;

procedure TLastControlForm.MyProc(Sender: TObject; IsMouse: boolean; ShiftState : TShiftState);
{-------------------------------------------------------------------------------------------------------------}
begin
      if IsMouse then begin
            self.ReasonLbl.Caption:='Mouse used';
      end else begin
            self.ReasonLbl.Caption:='Kbd used';
            if (ssAlt in ShiftState) or (ssCtrl in ShiftState) then begin
                  self.ReasonLbl.Caption:='ShortCut Used';
            end;
      end;
end;

procedure TLastControlForm.SetOnControlFocus(const Value: TOnControlFocus);
{-------------------------------------------------------------------------------------------------------------}
begin
  FOnControlFocus := Value;
end;

procedure TLastControlForm.WndProc(var Message: TMessage);
var
      ShiftState : TShiftState;
      KeyState: TKeyboardState;
begin
      case Message.Msg of
            WM_MOUSEFIRST..WM_MOUSELAST : begin
                  IsMouse:=True;
            end;
            CM_CHILDKEY : begin
                  IsMouse:=False;
                  ShiftState:=[]; //The bug is here ???
                  GetKeyboardState(KeyState);
                  {
                  if GetKeyboardState(VK_MENU) <> 0then begin
                        Include(ShiftState, ssAlt)
                  end;
                  if GetKeyState(VK_SHIFT) < 0 then begin
                        Include(ShiftState, ssShift);
                  end;
                  if GetKeyState(VK_CONTROL) < 0 then begin
                        Include(ShiftState, ssCtrl);
                  end;
                  if GetKeyState(VK_MENU) < 0 then begin
                        Include(ShiftState, ssAlt);
                  end;
                  }
                  ShiftState:=KeyboardStateToShiftState(KeyState);
            end;
      end;
      case Message.Msg of
            CM_FOCUSCHANGED : begin
                  if Self.LastFocusControl <> Self.ActiveControl then begin
                        FLastFocusControl:=Self.ActiveControl;
                  end;
                  if Assigned( Self.FOnControlFocus ) then begin
                        FOnControlFocus( FLastFocusControl, IsMouse, ShiftState );
                  end;
            end;
      end;
      inherited WndProc(Message);
end;

end.


I'll see you soon.

T++, Radler.
0
RadlerCommented:
I'm back.
The error was a bit foll. The variable ShiftState must be saved at the previous event. There is my actual solution.
Accept only with a A grade. I'm waiting for a reply if something dont work to total completude of solution.

The DFM

object LastControlForm: TLastControlForm
  Left = 293
  Top = 138
  Width = 870
  Height = 640
  Caption = 'LastControlForm'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  Visible = True
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object ReasonLbl: TLabel
    Left = 560
    Top = 24
    Width = 51
    Height = 13
    Caption = 'ReasonLbl'
  end
  object Label1: TLabel
    Left = 88
    Top = 16
    Width = 54
    Height = 13
    Caption = '&Accelerator'
    FocusControl = Edit1
  end
  object Edit1: TEdit
    Left = 88
    Top = 32
    Width = 121
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
  object Edit2: TEdit
    Left = 240
    Top = 56
    Width = 121
    Height = 21
    TabOrder = 1
    Text = 'Edit2'
  end
  object Edit3: TEdit
    Left = 488
    Top = 72
    Width = 121
    Height = 21
    TabOrder = 2
    Text = 'Edit3'
  end
  object Edit4: TEdit
    Left = 672
    Top = 136
    Width = 121
    Height = 21
    TabOrder = 3
    Text = 'Edit4'
  end
  object BitBtn1: TBitBtn
    Left = 96
    Top = 184
    Width = 75
    Height = 25
    Caption = 'BitBtn&1'
    TabOrder = 4
  end
  object BitBtn2: TBitBtn
    Left = 224
    Top = 192
    Width = 75
    Height = 25
    Caption = 'BitBtn&2'
    TabOrder = 5
  end
  object BitBtn3: TBitBtn
    Left = 392
    Top = 216
    Width = 75
    Height = 25
    Caption = 'BitBtn&3'
    TabOrder = 6
  end
  object BitBtn4: TBitBtn
    Left = 536
    Top = 240
    Width = 75
    Height = 25
    Caption = 'BitBtn&4'
    TabOrder = 7
  end
end


The PAS

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;


type
  TOnControlFocus = procedure( Sender : TObject; IsMouse : boolean; ShiftState : TShiftState) of object;
  TLastControlForm = class(TForm)
       Edit1: TEdit;
       Edit2: TEdit;
       Edit3: TEdit;
       Edit4: TEdit;
       BitBtn1: TBitBtn;
       BitBtn2: TBitBtn;
       BitBtn3: TBitBtn;
       BitBtn4: TBitBtn;
       ReasonLbl: TLabel;
       Label1: TLabel;
       procedure FormCreate(Sender: TObject);
  private
    IsMouse : boolean;
    ShiftState : TShiftState;
       FOnControlFocus: TOnControlFocus;
       procedure SetOnControlFocus(const Value: TOnControlFocus);
       { Private declarations }
  protected
      FLastFocusControl : TControl;
      procedure WndProc(var Message: TMessage); override;
      procedure MyProc( Sender : TObject; IsMouse : boolean; ShiftState : TShiftState);
  public
       { Public declarations }
       property LastFocusControl : TControl read FLastFocusControl;
       property OnControlFocus : TOnControlFocus read FOnControlFocus write SetOnControlFocus;
  end;

var
  LastControlForm: TLastControlForm;

implementation

{$R *.DFM}

procedure TLastControlForm.FormCreate(Sender: TObject);
{-------------------------------------------------------------------------------------------------------------}
begin
      FLastFocusControl:=Self.ActiveControl;
      Self.OnControlFocus:=Self.MyProc; //Force to this example only OK ?
end;

procedure TLastControlForm.MyProc(Sender: TObject; IsMouse: boolean; ShiftState : TShiftState);
{-------------------------------------------------------------------------------------------------------------}
begin
      if IsMouse then begin
            self.ReasonLbl.Caption:='Mouse used';
      end else begin
            self.ReasonLbl.Caption:='Kbd used';
            if (ssAlt in ShiftState) or (ssCtrl in ShiftState) then begin
                  self.ReasonLbl.Caption:='ShortCut Used';
            end;
      end;
end;

procedure TLastControlForm.SetOnControlFocus(const Value: TOnControlFocus);
{-------------------------------------------------------------------------------------------------------------}
begin
  FOnControlFocus := Value;
end;

procedure TLastControlForm.WndProc(var Message: TMessage);
var
      KeyState: TKeyboardState;
begin
      case Message.Msg of
            WM_MOUSEFIRST..WM_MOUSELAST : begin
                  IsMouse:=True;
            end;
            CM_CHILDKEY : begin
                  IsMouse:=False;
                  ShiftState:=[];
                  GetKeyboardState(KeyState);
                  ShiftState:=KeyboardStateToShiftState(KeyState);
            end;
      end;
      case Message.Msg of
            CM_FOCUSCHANGED : begin
                  if Self.LastFocusControl <> Self.ActiveControl then begin
                        FLastFocusControl:=Self.ActiveControl;
                  end;
                  if Assigned( Self.FOnControlFocus ) then begin
                        FOnControlFocus( FLastFocusControl, IsMouse, ShiftState );
                  end;
            end;
      end;
      inherited WndProc(Message);
end;

end.


Good job friend.

T++, Radler.
0
hatecaplettersAuthor Commented:
geobul >> looks VERY promising, but..
it doesn't tell me when I use eg. ALT+A (the accelerator key on a bitbtn which setsfocus to another editbox. Another problem is, if im in another editbox, then use SHIFT+TAB to get "back" to the first editbox, then click ALT+A to move to the next component, it still shows "shift" , and doesn't indicate what key was used in combination with the ALT key. And , if i use a menu item to get there (again, using the ALT key to move around in the menu), it doesn't react.

Radler >>> much of the same goes for your suggestion - plus, if i for some reason keep the CTRL key pressed while clicking a component, i get "shorcut" used"

I'm sure that I if I had had more knowledge about these matters I would be able to build the routine I want from these suggestions, but I don't. Thats why I'm offering so many points.

So, maybe I should be as specific as I can, explaining exactly what is I need:

When a control looses focus, I need one or more variables that I can access easily, telling me exactly why the control is loosing focus. I have to be able to see if it was because -

1. The mouse was clicked on another control.

2. the TAB key was used.

3.  the tab key was used in combination with the SHIFT key.

4. I in the onkeypress event handler of the control loosing focus moves focus to another control (in my case, i move focus to another control when the user hits the ENTER key).

5. an accelerator key on a visible control was used

whenever reason has to do with keys being pressed, i also need to know what key(s) where pressed.


I hope this can clarify somewhat what it is that I need

thanks for the work so far :-)

hatecapletters   (which incidently meen "hates capital letters" ;-)
0
RadlerCommented:
I'm happy now;
1st - You appear
2nd -Your specifications are clear
Looking this I saw that my fails are:
1 - The Mouse+Key=ShortCut or Key
2 - The Last key missing
I'm correting this. I'll try put the corrections today, maybe tomorow no contact availble, monday OK !

T++, Radler.
0
RadlerCommented:
Surprise !

At Brazil the slavery not finish yet, and I was forced to work today.
Well friend your problem is my prefered, and I dont go disapointer you.
This code/dfm works fine and is still light with a bonus of converting the key to a legible text.
Was a pleasure help.

** unit2.dfm **
object LastControlForm: TLastControlForm
  Left = 182
  Top = 160
  Width = 733
  Height = 493
  Caption = 'LastControlForm'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  Visible = True
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object ReasonLbl: TLabel
    Left = 490
    Top = 24
    Width = 51
    Height = 13
    Caption = 'ReasonLbl'
  end
  object Label1: TLabel
    Left = 18
    Top = 16
    Width = 54
    Height = 13
    Caption = '&Accelerator'
    FocusControl = Edit1
  end
  object ControlLbl: TLabel
    Left = 490
    Top = 48
    Width = 47
    Height = 13
    Caption = 'ControlLbl'
  end
  object KeyLbl: TLabel
    Left = 490
    Top = 8
    Width = 32
    Height = 13
    Caption = 'KeyLbl'
  end
  object Edit1: TEdit
    Left = 18
    Top = 32
    Width = 121
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
  object Edit2: TEdit
    Left = 170
    Top = 56
    Width = 121
    Height = 21
    TabOrder = 1
    Text = 'Edit2'
  end
  object Edit3: TEdit
    Left = 418
    Top = 72
    Width = 121
    Height = 21
    TabOrder = 2
    Text = 'Edit3'
  end
  object Edit4: TEdit
    Left = 602
    Top = 136
    Width = 121
    Height = 21
    TabOrder = 3
    Text = 'Edit4'
  end
  object BitBtn1: TBitBtn
    Left = 55
    Top = 184
    Width = 75
    Height = 25
    Caption = 'BitBtn&1'
    TabOrder = 4
  end
  object BitBtn2: TBitBtn
    Left = 224
    Top = 192
    Width = 75
    Height = 25
    Caption = 'BitBtn&2'
    TabOrder = 5
  end
  object BitBtn3: TBitBtn
    Left = 392
    Top = 216
    Width = 75
    Height = 25
    Caption = 'BitBtn&3'
    TabOrder = 6
  end
  object BitBtn4: TBitBtn
    Left = 536
    Top = 240
    Width = 75
    Height = 25
    Caption = 'BitBtn&4'
    TabOrder = 7
  end
end


** Unit2.pas **
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;


type
  TOnControlFocus = procedure( Sender : TObject; LastKey : word; IsMouse : boolean; ShiftState : TShiftState) of object;
  TLastControlForm = class(TForm)
       Edit1: TEdit;
       Edit2: TEdit;
       Edit3: TEdit;
       Edit4: TEdit;
       BitBtn1: TBitBtn;
       BitBtn2: TBitBtn;
       BitBtn3: TBitBtn;
       BitBtn4: TBitBtn;
       ReasonLbl: TLabel;
       Label1: TLabel;
    ControlLbl: TLabel;
    KeyLbl: TLabel;
       procedure FormCreate(Sender: TObject);
  private
       IsMouse : boolean;
    FLastKey : word;
       ShiftState : TShiftState;
       FOnControlFocus: TOnControlFocus;
       procedure SetOnControlFocus(const Value: TOnControlFocus);
       { Private declarations }
  protected
      FLastFocusControl : TControl;
      procedure WndProc(var Message: TMessage); override;
      procedure MyProc( Sender : TObject; LastKey : word; IsMouse : boolean; ShiftState : TShiftState);
  public
       { Public declarations }
       property LastFocusControl : TControl read FLastFocusControl;
       property OnControlFocus : TOnControlFocus read FOnControlFocus write SetOnControlFocus;
  end;

var
  LastControlForm: TLastControlForm;

implementation

{$R *.DFM}

function KeyName( lParam : LPARAM ) : string;
var
   KeyName: array[0..255] of Char;
   ScanCode : integer;
begin
   ScanCode := MapVirtualKey(lParam, 0) shl 16;
   GetKeyNameText( ScanCode, KeyName, SizeOf(KeyName));
   Result:=KeyName;
end;

procedure TLastControlForm.FormCreate(Sender: TObject);
{-------------------------------------------------------------------------------------------------------------}
begin
      FLastFocusControl:=Self.ActiveControl;
      Self.OnControlFocus:=Self.MyProc; //Force to this example only OK ?
end;

procedure TLastControlForm.MyProc( Sender : TObject; LastKey : word; IsMouse : boolean; ShiftState : TShiftState);
begin
   Self.ControlLbl.Caption:=TControl( Sender ).Name;
      Self.KeyLbl.Caption:=KeyName( LastKey );
   //VirtualKey
      if IsMouse then begin
            Self.ReasonLbl.Caption:='Mouse used';
      end else begin
            Self.ReasonLbl.Caption:='Kbd used';
            if (ssAlt in ShiftState) or (ssCtrl in ShiftState) then begin
                  Self.ReasonLbl.Caption:='ShortCut Used';
            end;
      end;
end;

procedure TLastControlForm.SetOnControlFocus(const Value: TOnControlFocus);
{-------------------------------------------------------------------------------------------------------------}
begin
  FOnControlFocus := Value;
end;

procedure TLastControlForm.WndProc(var Message: TMessage);
var
      KeyState: TKeyboardState;
begin
      case Message.Msg of
            WM_MOUSEFIRST..WM_MOUSELAST : begin
                  IsMouse:=True;
            end;
            CM_CHILDKEY : begin
                  IsMouse:=False;
                  GetKeyboardState(KeyState);
                  ShiftState:=KeyboardStateToShiftState(KeyState);
                  FLastKey:=Message.WParam;
            end;
            WM_PARENTNOTIFY : begin
                  if (Message.WParam = WM_LBUTTONDOWN ) or (Message.WParam = WM_RBUTTONDOWN ) then begin
                        IsMouse:=True;
                  end;
            end;
      end;

      case Message.Msg of
            CM_FOCUSCHANGED : begin
                  if Self.LastFocusControl <> Self.ActiveControl then begin
                        FLastFocusControl:=Self.ActiveControl;
                  end;
                  if Assigned( Self.FOnControlFocus ) then begin
                        FOnControlFocus( FLastFocusControl, FLastKey, IsMouse, ShiftState );
                  end;
            end;
      end;
      inherited WndProc(Message);
end;

end.

T++, Radler.
0
RadlerCommented:
Remember that the MyProcCode is the key part, and must be adapted to your real necessity.
Again, T++, Radler.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
hatecaplettersAuthor Commented:
that was quick :-)
I won't get a chance to look closer at it for a few days, so please be patient with my reply

hatecapletters
0
hatecaplettersAuthor Commented:
thanks a lot people !

I used the suggestions from both of you and managed to create a component I can place on a form to always have the informations I need available.

Geobull , since I mostly used the knowledge I learned from radler he gets the 800 points, but I've posted another Q with 250 points for you in the Delphi section.

this has been a very constructive learning experience for me, and I'm grateful for that :-)

take care
hatecapletters
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.