Solved

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

Posted on 2004-04-23
7
493 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
[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
  • 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
Technology Partners: 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!

 
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

Technology Partners: 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

Suggested Solutions

Title # Comments Views Activity
Delphi Form ownership 4 126
Delphi...Split view - idea? 1 116
CheckListBox usage 3 81
Delphi problems to abort a printjob 9 34
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

733 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