如何停止 TRadioButton 对箭头键的反应?
How to stop TRadioButton reacting at arrow keys?
我有一个面板,水平放置了几个 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;
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;
如果这不是一次性行为,我会按照维多利亚在问题评论中提到的那样编写一个容器控件。
我有一个面板,水平放置了几个 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;
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;
如果这不是一次性行为,我会按照维多利亚在问题评论中提到的那样编写一个容器控件。