如何停止在TForm上接收重复的OnKeyPress事件?

时间:2018-11-20 17:48:08

标签: forms delphi delphi-2009

我有一个主窗体,当我选择一个项目并按 Enter 时,将显示第二个模式窗体。它具有一些TEdit控件来更改项目参数。用户完成操作后,可以按 Esc 取消或按 Enter 更新该项目,然后关闭编辑表单。

问题在于,如果用户按住 Enter ,则会发生循环。关闭窗体,然后再次打开,然后关闭...等等。

我更改了模式表格的WndProc,并在按下了先前的键状态时取消了。但这仅在我对窗体没有任何控件的情况下有效。如果我放下TEdit(需要),则表单将重新进入循环。模态表单将KeyPreview设置为true,因为我希望能够从任何地方验证数据。

这是重现该问题的最少代码:

对此进行测试后,可以将TEdit放在Form2上,您会注意到发生了循环。

Form1:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
 if Key = #13 then Form2.ShowModal;
end;

end.

Form2:

unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  protected
    procedure WndProc(var Msg: TMessage); override;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
 KeyPreview:= True;
end;

procedure TForm2.FormKeyPress(Sender: TObject; var Key: Char);
begin
 if Key = #13 then begin Key:= #0; ModalResult:= mrOK; end;
end;

procedure TForm2.WndProc(var Msg: TMessage);
begin
 if (Msg.Msg = WM_CHAR) and ((Msg.LParam and $40000000) <> 0) then Exit;
 inherited;
end;

end.

1 个答案:

答案 0 :(得分:0)

由于无法挂起TWinControl.DoKeyPress来解决此问题,因此我想出了以下解决方法:

Form1:

procedure TForm1.FormCreate(Sender: TObject);
begin
 Application.OnActivate:= AppActivate;
end;

procedure TForm1.AppActivate(Sender: TObject);
begin
 EnterReleased:= (GetAsyncKeyState(VK_RETURN) and $8000) = 0;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
 if Key = #13 then begin
  Key:= #0;
  if EnterReleased then begin
   EnterReleased:= False;
   Form2.ShowModal;
  end;
 end;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if Key = VK_RETURN then EnterReleased:= True;
end;

Form2:

procedure TForm2.FormCreate(Sender: TObject);
begin
 KeyPreview:= True;
end;

procedure TForm2.FormKeyPress(Sender: TObject; var Key: Char);
begin
 if Key = #13 then begin
  Key:= #0;
  if EnterReleased then begin
   EnterReleased:= False;
   ModalResult:= mrOK;
  end;
 end;
end;

procedure TForm2.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if Key = VK_RETURN then EnterReleased:= True;
end;