Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Embedded Frames do not receive Shortcut key input

Posted on 2006-07-17
19
Medium Priority
?
1,153 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

604 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