Solved

Detect an Escape keystroke event don't know which component is getting focus?

Posted on 2004-04-23
7
488 Views
Last Modified: 2010-04-16
Anyone here please help me.

How can I detect an Escape keystroke even if I don't know which component is getting focus in runtime?

So I can do something like, whenener user press the Escape key, ShowMessage('I've press the Escape key');

Ah, one more question, the speed button (TSpeedButton) doesn't have .Cancel property as a button have which reponses to Escape keypress if .Cancel set to true.  How can I make a speed button response to Escape keypress? I tried to make a child class of TSpeedButton which has Cancel property but unsuccessful (maybe I didn't know how to do it).

Brimountain
0
Comment
Question by:brimountain
  • 3
  • 3
7 Comments
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10905858
First, set the form's KeyPreview property to True.

Then:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  begin
   if key = VK_ESCAPE then showmessage('Esc key.');
  end;


"Ah, one more question, the speed button (TSpeedButton) doesn't have .Cancel property as a button have which reponses to Escape keypress if .Cancel set to true.  How can I make a speed button response to Escape keypress? I tried to make a child class of TSpeedButton which has Cancel property but unsuccessful (maybe I didn't know how to do it). "

Not sure what you are doing here....?

Are you using this for a modal dialog?

Do you want the button to send a ModalResult  - i.e. mrCancel

procedure TForm1.Button1Click(Sender: TObject);
begin
 ModalResult:= mrCancel;
 Close;
end;

SHane
0
 
LVL 11

Expert Comment

by:ZhaawZ
ID: 10906678
Just use TForm.OnShortCut event!

procedure TForm1.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
if msg.CharCode = 27 then ShowMessage('I''ve pressed the Escape key');
//Handled := true;
end;

This event occurs before OnKeyDown event, and you can handle it.
0
 

Author Comment

by:brimountain
ID: 10907173
Hi shaneholmes and ZhaawZ

For my first question, I think both of you provided me the solution. Shaneholmes' method is absolutely correct.  But there is a prolem with Zhaawz's method. The problem is that although I pressed Escape key onece, it shown the message "I've just pressed Escape key twice". Do you know how to get around of this problem, ZhaawZ?

Your helps are very useful to me. Thank you very much!
--------------------
I want to clarify my second question below:

On my form, I have a button:

button1 : TButton;

I select button1 and open the object inspector and set the Cancel property of this button to TRUE. I run the program and in this program, pressing the escape key will trigger Button1Click event handler.

I remove button 1 and  put a speed button on my form:

SpeedButton1 : TSpeedButton;

I can not do as I did above with button1 because SpeedButton1 doesn't have SpeedButton1.Cancel property.

What I want is to do something so that pressing Escape key will trigger SpeedButton1Click event handler.

What I tried was to create a child class:

TmySpeedButton : class(TSpeedButton)
private
...
public
...
published
...
property Cancel : Boolean read....write....default false;
...
end;  

then I can have:

mySpeedButton1 : TmySpeedButton;
....
mySpeedButton1 : TmySpeedButton.Create(Self);
mySpeedButton1.Cancel := true;

Unfortunately, I was not successful.

Could you please help me to work it out or provide me different ways to make a speed button responses to an Escape keystroke?

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 11

Expert Comment

by:shaneholmes
ID: 10907191
First, set the form's KeyPreview property to True.

Then:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  begin
   if key = VK_ESCAPE then
    MySpeedButton.Click;
  end;

SHane
0
 

Author Comment

by:brimountain
ID: 10909480
Hi Shane

Your answer is right, but not what I expected. From your first answer, I already knew how to do:  

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  begin
   if key = VK_ESCAPE then  SpeedButton1.Click;
  end;

and this worked.

What I meaned in my question is whether I could make TmySpeedButton, a child class of TSpeedButton, which has the Cancel property like TButton. So I don't have to set the form's KeyPreview property to True and  need procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState) to make mySpeedButton1 response to an Escape keystroke. Instead, I just need to set .Cancel property to true and it goes.

(I am studying "Writing Delphi Components" and working on an assignment for it. Your answer is very helpful to me.Thank you very much)

Brimountain


 
0
 
LVL 11

Accepted Solution

by:
shaneholmes earned 100 total points
ID: 10909557
Im sure you could,

did you try looking in the source - (StdCtrls.pas) in the Source\VCL\ folder, at how TButton does it?


Here is what i think can be done......



TXSpeedButton = class(TSpeedButton)
  private
    fCancel: Boolean;
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
    protected
  public
  published
    property Cancel: Boolean read fCancel write fCancel default False;
  end;


procedure TXSpeedButton.CMDialogKey(var Message: TCMDialogKey);
begin
  with Message do
    if  (((CharCode = VK_RETURN) and FActive) or
      ((CharCode = VK_ESCAPE) and FCancel)) and
      (KeyDataToShiftState(Message.KeyData) = []) and CanFocus then
    begin
      Click;
      Result := 1;
    end else
      inherited;
end;

If that dont work, You may have to look at:

procedure CMDialogChar(var Message: TCMDialogChar);
procedure CMFocusChanged(var Message: TCMFocusChanged);


as well


Shane
0
 

Author Comment

by:brimountain
ID: 10917559
Thank you so much, but i am pretty busy nowadays. I'll try your comments when free and get back soon.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

757 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now