Delphi XE and Trapping Arrow Key with OnKeyDown

后端 未结 5 1554
闹比i
闹比i 2020-12-06 17:21

I want my form to handle the arrow keys, and I can do it -- as long as there is no button on the form. Why is this?

5条回答
  •  Happy的楠姐
    2020-12-06 18:00

    Key messages are processed by the controls themselves who receives these messages, that's why when you're on a button the form is not receiving the message. So normally you would have to subclass these controls, but the VCL is kind enough to ask the parenting form what to do if the form is interested:

    type
      TForm1 = class(TForm)
        ..
      private
        procedure DialogKey(var Msg: TWMKey); message CM_DIALOGKEY;
        ..
    
    
    procedure TForm1.DialogKey(var Msg: TWMKey); 
    begin
      if not (Msg.CharCode in [VK_DOWN, VK_UP, VK_RIGHT, VK_LEFT]) then
        inherited;
    end;
    

    François editing: to answer the OP original question, you need to call onKeyDown somehow so that his event code would work (feel free to edit; was too long for a comment).

    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
      private
        { Private declarations }
        procedure DialogKey(var Msg: TWMKey); message CM_DIALOGKEY;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.DialogKey(var Msg: TWMKey);
    begin
      case Msg.CharCode of
        VK_DOWN, VK_UP, VK_RIGHT, VK_LEFT:
          if Assigned(onKeyDown) then
            onKeyDown(Self, Msg.CharCode, KeyDataToShiftState(Msg.KeyData));
        else
          inherited
      end;
    end;
    
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      case Key of
        VK_DOWN: Top := Top + 5;
        VK_UP: Top := Top - 5;
        VK_LEFT: Left := Left - 5;
        VK_RIGHT: Left := Left + 5;
      end;
    end;
    

提交回复
热议问题