当在TCheckBox或TButton控件上按下VK_LEFT键时,是否有办法触发OnKeyDown事件。目前,它只是选择另一个控件,但不会触发该事件。
更新
以下是我使用密钥VK_LEFT的代码,如TAB Back。
首先,我需要在某些控件上禁用VK_LEFT的标准行为,例如(TCheckBox,TButton,...):
procedure TfmBase.CMDialogKey(var Message: TCMDialogKey);
begin
if Message.CharCode <> VK_LEFT then
inherited;
end;
然后,在TCheckBox,TButton上为VK_LEFT触发了OnKeyDown事件......在那个事件中,我放置了代码来选择前一个控件。 KeyPreview当然必须是真的。
procedure TfmBase.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
handled: Boolean;
begin
if Key = VK_LEFT then
begin
handled := false;
TabBack(handled); //This is my function, which checks the type of the control and selects the previous control.
if handled then
Key := 0;
end;
end;
答案 0 :(得分:5)
您不会触发该事件,因为该按键被解释为表单导航。顶级消息循环识别出这是一个导航键并转移消息以执行该导航。
如果你想处理这个事件,那么你唯一的机会是Application.OnMessage
,它会在消息被转移之前触发。
<强>更新强>
在评论中,您表示要拦截此事件以执行导航。由于事件未触发,因为正在执行默认导航,因此理想的解决方案可能是覆盖默认导航。
我认为推动此问题的关键例程是TWinControl.CNKeyDown
。阅读此代码,我认为您只需在表单中处理CM_DIALOGKEY
并说服导航按您希望的方式运行。
您的代码应如下所示:
procedure TMyForm.CMDialogKey(var Message: TCMDialogKey);
begin
if GetKeyState(VK_MENU) >= 0 then begin
case Message.CharCode of
VK_LEFT:
if ActiveControl=MyControl1 then begin
MyControl2.SetFocus;
Message.Result := 1;
Exit;
end;
end;
end;
inherited;
end;
答案 1 :(得分:3)
您需要处理WM_GETDLGCODE
消息:
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
....
procedure TfmBase.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result:=DLGC_WANTALLKEYS or DLGC_WANTARROWS;
end;