我有一个水平放置几个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;
答案 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;
如果这不是一次性行为,我会去写一个容器控件,就像维多利亚在对该问题的评论中提到的那样。