代码之家  ›  专栏  ›  技术社区  ›  Marus Gradinaru

如何停止在tform上接收重复的onkeypress事件?

  •  -1
  • Marus Gradinaru  · 技术社区  · 6 年前

    我有一个主窗体,当我选择一个项目并按 进入 显示了第二种模态形式。这有一些 TEdit 控件更改项参数。用户完成后,可以按 ESC 取消或 进入 更新项目并关闭编辑表单。

    问题是如果用户按下并保持 进入 ,将发生循环。表单被关闭并再次打开,然后关闭…等等。

    我改变了 WndProc 如果按下上一个键状态,则取消。但只有在表单上没有任何控件时,此操作才有效。如果我掉一个 特迪特 (这是必需的),表单重新进入循环。模态形式有 KeyPreview 设置为true,因为我希望能够从任何地方验证数据。

    这是再现问题的最小代码:

    测试后,你可以 特迪特 Form2 你会注意到一个循环发生了。

    形式1:

    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.
    

    形式2:

    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 回复  |  直到 6 年前
        1
  •  0
  •   Marus Gradinaru    6 年前

    因为不可能钩住 TWinControl.DoKeyPress 为了解决这个问题,我想出了一个解决办法:

    形式1:

    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;
    

    形式2:

    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;