?
Solved

Embedded Frames do not receive Shortcut key input

Posted on 2006-07-17
19
Medium Priority
?
1,123 Views
Last Modified: 2010-04-05
Dear Experts,

I am using TFrames in Delphi 7.

At application's main form create I create my Frames all descent from TBaseFrame.
These frames then get's showed and hide on the appropriate button's onclick() events.

The problem I have here is there are 2 frames which have a TListView component on it.
I have created an action to select / deselect all items in the TListView components.
The shortcut key for these actions are CTRL+A.

Ok, when I show my first Frame the CTRL+A is working but when showing the second and hiding the first the input still goes to the first (hidden) frame.

How can I force the keyboard input to the visible Frame?

Thanks in advance!
0
Comment
Question by:Marius0188
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 4
  • 3
  • +1
19 Comments
 

Author Comment

by:Marius0188
ID: 17126923
I should also mention that I have tried:
SetFocus()
BringToFront()
SentToBack()
and it's not working.
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 17127562
Make KeyPreview = True on your form. This will make sure your form receive the Key pressed before all other controls. The in OnKeyDown, OnKeyUp, OnKeyPress handle the events.
0
 

Author Comment

by:Marius0188
ID: 17130398
Can you maybe please show me the code for OnKeyDown, OnKeyUp and OnKeyPress events to effectively forward all key strokes to a TFrame?

Thanks so far!
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 12

Expert Comment

by:Ivanov_G
ID: 17131526
Example:

parent form:
------------------------------------------------------
uses Unit2;

procedure TForm1.FormCreate(Sender: TObject);
var
  Frame2 : TFrame2;
begin
  Frame2 := TFrame2.Create(Self);
  Frame2.Parent := Panel1;
  Frame2.Align := alClient;
  Frame2.Show;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var
  i : Integer;
begin
  for i := 0 to Self.ComponentCount - 1 do
    begin
      if (Self.Components[i] is TFrame) then
        if ((Self.Components[i] as TFrame).Visible) and ((Self.Components[i] as TFrame).Name = 'Frame2') then
          begin
            // frame is visible
            (Self.Components[i] as TFrame).Perform(WM_KEYDOWN, ord(Key), 0);
          end;
    end;
end;

-------------------------------------------------------------------------------
frame:
-------------------------------------------------------------------------------

type
  TFrame2 = class(TFrame)
  private
    { Private declarations }
    procedure OnKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN;
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

{ TFrame2 }

procedure TFrame2.OnKeyDown(var Msg: TWMKeyDown);
begin
  ShowMessage(IntToStr(Msg.CharCode));
end;
0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 17133604
procedure PassKeyToFrame(aParent: TWinControl; aKey: TWMKey; var aHandled: Boolean );
var
  a_iIndex: integer;
begin
  for a_iIndex := 0 to aParent.ControlCount -1 do
  begin
  {we loop through all the children}
    if aParent.Controls[a_iIndex] is TBaseFrame then
    begin
      aHandled := TBaseFrame(aParent.Controls[a_iIndex]).HandleKey(aKey);
      if aHandled then
        break;
    end;
    if aParent.Controls[a_iIndex] is TWinControl then
{if its a WinControl...meaning it can be a Parent to other controls...we loop
 through them, and so and so on.}
      PassKeyToFrame(TWinControl(aParent.Controls[a_iIndex]), aKey, aHandled);
  end;
end;

procedure TForm1.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  PassKeyToFrame(Form1, Msg, Handled);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Frame1 := TBaseFrame.Create(Self);
  Frame1.Parent := Panel1;
end;


type
  TBaseFrame = class(TFrame)
    Label1: TLabel;
    Button1: TButton;
  private
    { Private declarations }
  public
    { Public declarations }
    function HandleKey(aKey: TWMKey): boolean;
  end;


{ TBaseFrame }

function TBaseFrame.HandleKey(aKey: TWMKey): boolean;
begin
  Result := Visible;
  if Result then
    ShowMessage('rcvd');
end;
0
 

Author Comment

by:Marius0188
ID: 17133759
Thanks all so far.

1. May I ask why does the visible Frame not automatically receive keystrokes?
Why does it feel like I have to hack it (or something like that) in order to work normal?
If one frame is hidden and another frame is visible isn't it logical that the hidden one should not respond to keystrokes
but instead the visible one? Can someone please explain to me why?


2. I have quickly looked over all the comments and it feels to me there should be a simple more elegant way of handling this. Please understand I am not being difficult. :)
a) But can't I just force a Frame to be the ActiveControl of my MainForm?
The comments if not complex at all but like I said. If embedding Frames in a TForm is should behave like any other control? Or not?

0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 17134012
procedure EnableFrame(aFrame: TFrame; aEnable: boolean);
begin
  aFrame.Visible := aEnable;
  aFrame.Enabled := aEnable;
  if aFrame.Enabled then
    if aFrame.CanFocus then
      Form1.ActiveControl := aFrame;
end;

when you make the Frame Not Visible...also set it Not Enabled ...that should stop it from getting keyboard input
0
 

Author Comment

by:Marius0188
ID: 17135164
I have tried enabling and disabling the frame according to it's visible state.
Have also set ActiveControl but still it's not working.

0
 

Author Comment

by:Marius0188
ID: 17135177
Maybe I should mention.
On my MainForm I have a TPanel which is Parent control of Frames.
0
 

Author Comment

by:Marius0188
ID: 17135199
Just for testing purposes I have set
the Frame.Parent := nil when hidden.

Then the Key stokes are working fine but obviously lots of errors.
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 17136391
In my example I used

Form1.KeyPreview := true;
Frame.Parent := Panel1;
0
 
LVL 21

Expert Comment

by:ziolko
ID: 17136652
try this:
PostMessage(valid_handke_here, WM_ACTIVATE, WA_ACTIVE, 0);

ziolko.
0
 

Author Comment

by:Marius0188
ID: 17136737
Hi All,

I have tried everything so far to get the Frame to be the active control.
Nothing is working.
Maybe if I show my code you will understand better.



procedure TfrmMain.SetCurrentFrame(const Value: TBaseFrame);
begin
  If Assigned(CurrentFrame) then
  begin
    If CurrentFrame = Value then Exit;
    CurrentFrame.Enabled := False;
    CurrentFrame.Hide;
  end;

  FCurrentFrame := Value;

  CurrentFrame.Enabled := True;
  CurrentFrame.Parent := panMain;
  CurrentFrame.Align := alClient;
  CurrentFrame.Show;

  CurrentFrame.LoadData;

  frmMain.ActiveControl := CurrentFrame;

//  frmMain.ActiveControl := CurrentFrame;
//    frmMain.FocusControl(CurrentFrame);
//  CurrentFrame.BringToFront;
//  CurrentFrame.SetFocus;
 
end;
0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 17139220
Can I see the code that you are executing on Ctrl + A

Are you using an ActionList?
0
 

Author Comment

by:Marius0188
ID: 17174804
Yes I am using a TActionList and assign my shortcuts via actions properties.
0
 

Author Comment

by:Marius0188
ID: 17175289
This is the code executed on the action which have the shortcut: CTRL+A.
-----------------------------------------------------------------------------------------
procedure TAnalyzeFrame.actSelectAllExecute(Sender: TObject);
begin
  inherited;
  Busy := True;
  Try
    Case tbtnSelectAll.Tag of
      0:
        begin
          tbtnSelectAll.Tag := 1;
          lsvDownloads.SelectAll;
        end;
      1:
        begin
          tbtnSelectAll.Tag := 0;
          lsvDownloads.ClearSelection;
        end;
    end;
  Finally
    Busy := False;
  end;
end;
-----------------------------------------------------------------------------

Please note that there are another frame with similar action to select all in it's TListView.
0
 
LVL 6

Accepted Solution

by:
House_of_Dexter earned 500 total points
ID: 17178094
k...do you have an actionlist for each frame?

If so...  ActionList1.State :=  asSuspended for the disabled frame; and   ActionList1.State :=  asNormal for the visible frame;

This will stop the ActionList from grabbing Shortcuts...

0
 

Author Comment

by:Marius0188
ID: 17178179
Yes the 2 Frames giving problems each have their own TActionList.

Ok I will test your example and let you know.

Thanks!
0
 

Author Comment

by:Marius0188
ID: 17178442
OK thanks House of Dexter.

It worked!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Suggested Courses
Course of the Month10 days, 5 hours left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question