如何停止TRadioButton对箭头键做出反应?

时间:2018-07-12 14:13:22

标签: delphi radio-button delphi-2009

我有一个水平放置几个TRadioButton的面板。如果最左边的按钮已聚焦,而我按向左箭头,则焦点会跳到最右边的按钮。我想停止所有箭头到达边缘时的行为。可能吗 ? 我尝试覆盖WM_KEYDOWN,但是当按下箭头键时,按钮永远不会收到此消息。

  TRadioButton = class(StdCtrls.TRadioButton)
  protected
    procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
    procedure WMKeyUp(var Message: TWMKeyUp); message WM_KEYUP;
  public
    BlockLeft, BlockRight: Boolean;
    constructor Create(AOwner: TComponent); override;
  end;

constructor TRadioButton.Create(AOwner: TComponent);
begin
 inherited;
 BlockLeft:= False;
 BlockRight:= False;
end;

procedure TRadioButton.WMKeyDown(var Message: TWMKeyDown);
begin
 if BlockLeft and (Message.CharCode = VK_LEFT) then Exit;
 if BlockRight and (Message.CharCode = VK_RIGHT) then Exit;

 inherited;
end;

procedure TRadioButton.WMKeyUp(var Message: TWMKeyUp);
begin
 if BlockLeft and (Message.CharCode = VK_LEFT) then Exit;
 if BlockRight and (Message.CharCode = VK_RIGHT) then Exit;
 inherited;
end;

1 个答案:

答案 0 :(得分:4)

VCL将键盘消息偏移为控件通知,并将其发送到消息的目标控件。因此,您应该改为截获CN_KEYDOWN消息。

如果这是一次性的设计考虑,我宁愿在表单级别处理此行为,因为IMO控件本身并不在意放置在何处。对于所有单选按钮都应表现相似的表单,示例如下:

procedure TForm1.CMDialogKey(var Message: TCMDialogKey);
begin
  if ActiveControl is TRadioButton then
    case Message.CharCode of
      VK_LEFT, VK_UP: begin
        if ActiveControl.Parent.Controls[0] = ActiveControl then begin
          Message.Result := 1;
          Exit;
        end;
      end;
      VK_RIGHT, VK_DOWN: begin
        if ActiveControl.Parent.Controls[ActiveControl.Parent.ControlCount - 1]
            = ActiveControl then begin
          Message.Result := 1;
          Exit;
        end;
      end;
    end;
  inherited;
end;


如果这不是一次性行为,我会去写一个容器控件,就像维多利亚在对该问题的评论中提到的那样。