0
votes

I'm experiencing a weird issue with trapping the escape key in our main application. I created a simple test form to see what might be going wrong, since pressing the escape key was previously working. So far, it's still not working and I'm unsure why.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Button2KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.message = WM_KeyDown then
    showmessage('MSG');
end;

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

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

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if key = vk_escape then
    Button1Click(sender);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showmessage('Button1Click');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := OnAppMessage;

  button1.Cancel := True; // set at design time as well
  self.KeyPreview := True; // set at design time as well
end;

end.

For some reason when pressing escape, it doesn't break on the point I placed in button1.OnKeyDown or even for the Application message WM_KEYDOWN -- all other keys break here. I tested my keyboard just to make sure the key was functioning and it's good.

Is there something that might be causing this or that I'm doing wrong?

Thanks.

3
I know, it has me baffled. Going to reboot one more time.fourwhey
I doubt reboot will change something. In your TApplicationEvents.OnMessage handler you should be able to receive the message; OnKeyDown should be suppressed by the Cancel property of your button.TLama
Wow, I should have made a video of this happening, because now it's working. How frustrating and embarrassing that I spent as much on it as I did since simply rebooting fixed it. :( I thought I rebooted on Friday and was thinking about why this might be happening this weekend, then took another look this morning. I should have made sure to do that earlier.fourwhey
Hm, the next time before I doubt about something I'll post a link to a possible solution :-)TLama

3 Answers

0
votes

Add this to your component's class:

procedure HandleDlgCode(var Msg:TMessage); message WM_GETDLGCODE;

and then in the implementation section:

procedure TComponentClass.HandleDlgCode(var Msg:TMessage);
var

  M: PMsg;

begin

  Msg.Result := DLGC_WANTALLKEYS or DLGC_WANTESCAPE or DLGC_WANTCHARS or DLGC_HASSETSEL;

  if Msg.lParam <> 0 then

    begin

      M := PMsg(Msg.lParam);

      case M.message of

        WM_KEYESCAPE, WM_CHAR:

        begin

          Perform(M.message, M.wParam, M.lParam);

          Msg.Result := Msg.Result or DLGC_WANTMESSAGE;

        end;

      end;

    end

  else

    Msg.Result := Msg

end;
0
votes

This is because you set the Cancel property for Button1 to True. Comment the line:

button1.Cancel := True;

and you will be able to catch Escape key. These wo ar mutualy exclusive.

0
votes

Try rebooting first. It fixed the issue.