Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnKeyDown event not fired when pressing VK_LEFT on TComboBox or TButton

Tags:

delphi

Is there a way to get the OnKeyDown event fired, when the VK_LEFT key is pressed on the TCheckBox or TButton control. Currently, it just selects another control, but doesn't fire that event.

UPDATE

Here is my code to use the key VK_LEFT like a TAB Back.

First, I needed to disable the standard behaviour of VK_LEFT on some controls like (TCheckBox, TButton, ...):

procedure TfmBase.CMDialogKey(var Message: TCMDialogKey);
begin
  if Message.CharCode <> VK_LEFT then
    inherited;
end;

then, the OnKeyDown event is also fired for VK_LEFT on TCheckBox, TButton, ... On that event I placed the code to select the previous control. KeyPreview must be true of course.

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;
like image 335
markus_ja Avatar asked Feb 21 '11 09:02

markus_ja


1 Answers

You won't get that event to fire because that key press is interpreted as form navigation. The top level message loop recognises that this is a navigation key and diverts the message to perform that navigation.

If you want to handle this event then your only opportunity to do so is in Application.OnMessage which fires before the message is diverted.

UPDATE

In a comment you indicate that you want to intercept this event in order to perform navigation. Since the event is not firing because default navigation is being performed, perhaps the ideal solution is to override the default navigation.

I believe that the key routine that drives this is TWinControl.CNKeyDown. Reading through this code, I think you just need to handle CM_DIALOGKEY in your form and persuade the navigation to behave the way you want it to.

Your code should look something like this:

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;
like image 96
David Heffernan Avatar answered Oct 24 '22 01:10

David Heffernan